diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index fc9c55e7868f4..d1cf0300b9e17 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -17,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 @@ -30,32 +31,23 @@ /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/plugins/vis_type @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/dev_tools/ @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/console_legacy @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/sample_data/ @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/charts/public/static/color_maps @elastic/kibana-app #CC# /src/plugins/index_pattern_management/public @elastic/kibana-app -#CC# /src/plugins/input_control_vis/ @elastic/kibana-app -#CC# /src/plugins/kibana_legacy/ @elastic/kibana-app -#CC# /src/plugins/timelion @elastic/kibana-app #CC# /x-pack/legacy/plugins/dashboard_mode/ @elastic/kibana-app #CC# /x-pack/plugins/dashboard_mode @elastic/kibana-app -#CC# /x-pack/plugins/lens/ @elastic/kibana-app # App Architecture /examples/bfetch_explorer/ @elastic/kibana-app-arch @@ -147,6 +139,7 @@ /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 @@ -351,6 +344,8 @@ 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 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/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/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 e314e55c34085..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] @@ -168,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] @@ -259,7 +259,7 @@ which will load the visualization's editor. [discrete] === x-pack/plugins -[%header,cols=2*] +[%header,cols=2*] |=== |Name |Description @@ -515,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): @@ -523,10 +527,6 @@ 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] 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/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.expressionrenderdefinition.displayname.md index 9d5f7609ee6cd..a957ecd63f043 100644 --- 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 @@ -9,5 +9,5 @@ A user friendly name of the renderer as will be displayed to user in UI. Signature: ```typescript -displayName: string; +displayName?: string; ``` 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 index e936e25cee6ca..8ae5aa2f1790e 100644 --- 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 @@ -9,5 +9,5 @@ A user friendly name of the renderer as will be displayed to user in UI. Signature: ```typescript -displayName: string; +displayName?: string; ``` 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/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..6fd30690b988e 100644 --- a/docs/user/dashboard/vega-reference.asciidoc +++ b/docs/user/dashboard/vega-reference.asciidoc @@ -11,10 +11,10 @@ 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 +* experimental[] Using the Elastic Map Service in Vega maps * Additional tooltip styling * Advanced setting to enable URL loading from any domain * Limited debugging support using the browser dev tools @@ -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/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/package.json b/package.json index e70b0386bf5e7..b2252e2bd264b 100644 --- a/package.json +++ b/package.json @@ -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.4.2", "color": "1.0.3", "commander": "^3.0.2", - "core-js": "^3.6.4", + "core-js": "^3.6.5", "cypress-promise": "^1.1.0", "deep-freeze-strict": "^1.1.1", "del": "^5.1.0", @@ -181,7 +178,7 @@ "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", @@ -214,6 +211,7 @@ "rxjs": "^6.5.5", "seedrandom": "^3.0.5", "semver": "^5.7.0", + "source-map-support": "^0.5.19", "style-it": "^2.1.3", "symbol-observable": "^1.2.0", "tar": "4.4.13", @@ -227,10 +225,12 @@ "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", @@ -238,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", @@ -261,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", @@ -291,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", @@ -331,19 +332,19 @@ "@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.21", + "@types/webpack": "^4.41.3", "@types/webpack-env": "^1.15.2", "@types/zen-observable": "^0.8.0", "@typescript-eslint/eslint-plugin": "^3.10.0", @@ -356,7 +357,7 @@ "archiver": "^3.1.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", @@ -382,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", @@ -411,10 +412,10 @@ "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", @@ -470,15 +471,15 @@ "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.16.1", + "vega": "^5.17.0", "vega-lite": "^4.16.8", "vega-schema-url-parser": "^2.1.0", "vega-tooltip": "^0.24.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-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 062520f47f0f9..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", diff --git a/packages/kbn-dev-utils/package.json b/packages/kbn-dev-utils/package.json index a85f5924f0ea2..a51734168cf76 100644 --- a/packages/kbn-dev-utils/package.json +++ b/packages/kbn-dev-utils/package.json @@ -10,7 +10,7 @@ "kbn:watch": "yarn build --watch" }, "dependencies": { - "@babel/core": "^7.11.1", + "@babel/core": "^7.11.6", "@kbn/utils": "1.0.0", "axios": "^0.19.2", "chalk": "^4.1.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/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/package.json b/packages/kbn-es/package.json index 40d34c5d710bb..c3733094350be 100644 --- a/packages/kbn-es/package.json +++ b/packages/kbn-es/package.json @@ -9,7 +9,7 @@ "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": "^3.0.0", "chalk": "^4.1.0", 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-i18n/package.json b/packages/kbn-i18n/package.json index 9e0ec50fb838e..f23faecbeaa67 100644 --- a/packages/kbn-i18n/package.json +++ b/packages/kbn-i18n/package.json @@ -13,7 +13,7 @@ }, "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", 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 430dac6cb2e00..4d415e96389df 100644 --- a/packages/kbn-interpreter/package.json +++ b/packages/kbn-interpreter/package.json @@ -16,7 +16,7 @@ }, "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", diff --git a/packages/kbn-optimizer/package.json b/packages/kbn-optimizer/package.json index f90fcaec79fe0..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.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/src/cli/index.js b/packages/kbn-optimizer/src/node/index.ts similarity index 92% rename from src/cli/index.js rename to packages/kbn-optimizer/src/node/index.ts index 45f88eaf82a5b..64dd75ce573e6 100644 --- a/src/cli/index.js +++ b/packages/kbn-optimizer/src/node/index.ts @@ -17,6 +17,4 @@ * under the License. */ -require('../apm')(); -require('../setup_node_env'); -require('./cli'); +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/src/setup_node_env/babel_register/index.js b/packages/kbn-optimizer/src/node/polyfill.ts similarity index 81% rename from src/setup_node_env/babel_register/index.js rename to packages/kbn-optimizer/src/node/polyfill.ts index 1574be8937a29..5d445ef89f71e 100644 --- a/src/setup_node_env/babel_register/index.js +++ b/packages/kbn-optimizer/src/node/polyfill.ts @@ -17,8 +17,4 @@ * under the License. */ -// register and polyfill need to happen in this -// order and in separate files. Checkout each file -// for a much more detailed explanation -require('./register'); -require('./polyfill'); +import 'core-js/stable'; diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts index 2edf1c999888e..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], diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json index 65b44b6965048..a2c4e1e2134e7 100644 --- a/packages/kbn-plugin-helpers/package.json +++ b/packages/kbn-plugin-helpers/package.json @@ -18,7 +18,7 @@ "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" }, diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 7dcfc1d778ea8..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__(496); +/* 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__(275); +/* 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__(276); +/* 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__(489); -/* 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__(284); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(388); -/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(389); +/* 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__(277); -/* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(282); -/* harmony import */ var _utils_yarn_lock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(279); -/* harmony import */ var _utils_validate_yarn_lock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(283); +/* 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__(275); +/* 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__(232); +/* 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__(267); +/* 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,1863 +23876,1279 @@ function spawnStreaming(command, args, opts, { } /***/ }), -/* 227 */ +/* 228 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const ansiStyles = __webpack_require__(113); -const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(228); -const { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -} = __webpack_require__(230); - -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__(231); - } + 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"; -const os = __webpack_require__(120); -const tty = __webpack_require__(121); -const hasFlag = __webpack_require__(229); -const {env} = process; +const cp = __webpack_require__(229); +const parse = __webpack_require__(231); +const enoent = __webpack_require__(242); -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; +function spawn(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); + + // Spawn the child process + const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + + // 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 spawned; } -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 spawnSync(command, args, options) { + // Parse the arguments + const parsed = parse(command, args, options); -function translateLevel(level) { - if (level === 0) { - return false; - } + // Spawn the child process + const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; + // 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 result; } -function supportsColor(haveStream, streamIsTTY) { - if (forceColor === 0) { - return 0; - } +module.exports = spawn; +module.exports.spawn = spawn; +module.exports.sync = spawnSync; - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } +module.exports._parse = parse; +module.exports._enoent = enoent; - if (hasFlag('color=256')) { - return 2; - } - if (haveStream && !streamIsTTY && forceColor === undefined) { - return 0; - } +/***/ }), +/* 231 */ +/***/ (function(module, exports, __webpack_require__) { - const min = forceColor || 0; +"use strict"; - if (env.TERM === 'dumb') { - return min; - } - 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; - } +const path = __webpack_require__(4); +const resolveCommand = __webpack_require__(232); +const escape = __webpack_require__(238); +const readShebang = __webpack_require__(239); - return 1; - } +const isWin = process.platform === 'win32'; +const isExecutableRegExp = /\.(?:com|exe)$/i; +const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } +function detectShebang(parsed) { + parsed.file = resolveCommand(parsed); - return min; - } + const shebang = parsed.file && readShebang(parsed.file); - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } + if (shebang) { + parsed.args.unshift(parsed.file); + parsed.command = shebang; - if ('GITHUB_ACTIONS' in env) { - return 1; - } + return resolveCommand(parsed); + } - if (env.COLORTERM === 'truecolor') { - return 3; - } + return parsed.file; +} - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); +function parseNonShell(parsed) { + if (!isWin) { + return parsed; + } - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } + // Detect & add support for shebangs + const commandFile = detectShebang(parsed); - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } + // We don't need a shell if the command filename is an executable + const needsShell = !isExecutableRegExp.test(commandFile); - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } + // 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); - if ('COLORTERM' in env) { - return 1; - } + // 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); - return min; -} + // Escape command & arguments + parsed.command = escape.command(parsed.command); + parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); -function getSupportLevel(stream) { - const level = supportsColor(stream, stream && stream.isTTY); - return translateLevel(level); -} + const shellCommand = [parsed.command].concat(parsed.args).join(' '); -module.exports = { - supportsColor: getSupportLevel, - stdout: translateLevel(supportsColor(true, tty.isatty(1))), - stderr: translateLevel(supportsColor(true, tty.isatty(2))) -}; + 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; +} -/***/ }), -/* 229 */ -/***/ (function(module, exports, __webpack_require__) { +function parse(command, args, options) { + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; + } -"use strict"; + 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); +} -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); -}; +module.exports = parse; /***/ }), -/* 230 */ +/* 232 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringReplaceAll = (string, substring, replacer) => { - let index = string.indexOf(substring); - if (index === -1) { - return string; - } +const path = __webpack_require__(4); +const which = __webpack_require__(233); +const pathKey = __webpack_require__(237)(); - 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); +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; - returnValue += string.substr(endIndex); - return returnValue; -}; + // 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 */ + } + } -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); + let resolved; - returnValue += string.substr(endIndex); - return returnValue; -}; + 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); + } + } -module.exports = { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -}; + // 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); + } + + return resolved; +} + +function resolveCommand(parsed) { + return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); +} + +module.exports = resolveCommand; /***/ }), -/* 231 */ +/* 233 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +const isWindows = process.platform === 'win32' || + process.env.OSTYPE === 'cygwin' || + process.env.OSTYPE === 'msys' -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 path = __webpack_require__(4) +const COLON = isWindows ? ';' : ':' +const isexe = __webpack_require__(234) -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); +const getNotFoundError = (cmd) => + Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) -function unescape(c) { - const u = c[0] === 'u'; - const bracket = c[1] === '{'; +const getPathInfo = (cmd, opt) => { + const colon = opt.colon || COLON - if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } + // 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 (u && bracket) { - return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); - } + if (isWindows) { + if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') + pathExt.unshift('') + } - return ESCAPES.get(c) || c; + return { + pathEnv, + pathExt, + pathExtExe, + } } -function parseArguments(name, arguments_) { - const results = []; - const chunks = arguments_.trim().split(/\s*,\s*/g); - let matches; +const which = (cmd, opt, cb) => { + if (typeof opt === 'function') { + cb = opt + opt = {} + } + if (!opt) + opt = {} - 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}')`); - } - } + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] - return results; -} + const step = i => new Promise((resolve, reject) => { + if (i === pathEnv.length) + return opt.all && found.length ? resolve(found) + : reject(getNotFoundError(cmd)) -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw - const results = []; - let matches; + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; + resolve(subStep(p, i, 0)) + }) - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } + 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)) + }) + }) - return results; + return cb ? step(0).then(res => cb(null, res), cb) : step(0) } -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, styles] of Object.entries(enabled)) { - if (!Array.isArray(styles)) { - continue; - } - - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } +const whichSync = (cmd, opt) => { + opt = opt || {} - current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; - } + const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) + const found = [] - return current; -} + for (let i = 0; i < pathEnv.length; i ++) { + const ppRaw = pathEnv[i] + const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw -module.exports = (chalk, temporary) => { - const styles = []; - const chunks = []; - let chunk = []; + const pCmd = path.join(pathPart, cmd) + const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd + : pCmd - // 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'); - } + 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) {} + } + } - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(character); - } - }); + if (opt.all && found.length) + return found - chunks.push(chunk.join('')); + if (opt.nothrow) + return null - if (styles.length > 0) { - const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMessage); - } + throw getNotFoundError(cmd) +} - return chunks.join(''); -}; +module.exports = which +which.sync = whichSync /***/ }), -/* 232 */ +/* 234 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var fs = __webpack_require__(134) +var core +if (process.platform === 'win32' || global.TESTING_WINDOWS) { + core = __webpack_require__(235) +} else { + core = __webpack_require__(236) +} -const path = __webpack_require__(4); -const childProcess = __webpack_require__(233); -const crossSpawn = __webpack_require__(234); -const stripFinalNewline = __webpack_require__(247); -const npmRunPath = __webpack_require__(248); -const onetime = __webpack_require__(249); -const makeError = __webpack_require__(251); -const normalizeStdio = __webpack_require__(256); -const {spawnedKill, spawnedCancel, setupTimeout, setExitHandler} = __webpack_require__(257); -const {handleInput, getSpawnedResult, makeAllStream, validateInputSync} = __webpack_require__(258); -const {mergePromise, getSpawnedPromise} = __webpack_require__(265); -const {joinCommand, parseCommand} = __webpack_require__(266); +module.exports = isexe +isexe.sync = sync -const DEFAULT_MAX_BUFFER = 1000 * 1000 * 100; +function isexe (path, options, cb) { + if (typeof options === 'function') { + cb = options + options = {} + } -const getEnv = ({env: envOption, extendEnv, preferLocal, localDir, execPath}) => { - const env = extendEnv ? {...process.env, ...envOption} : envOption; + if (!cb) { + if (typeof Promise !== 'function') { + throw new TypeError('callback not provided') + } - if (preferLocal) { - return npmRunPath.env({env, cwd: localDir, execPath}); - } + return new Promise(function (resolve, reject) { + isexe(path, options || {}, function (er, is) { + if (er) { + reject(er) + } else { + resolve(is) + } + }) + }) + } - return env; -}; + 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) + }) +} -const handleArgs = (file, args, options = {}) => { - const parsed = crossSpawn._parse(file, args, options); - file = parsed.command; - args = parsed.args; - options = parsed.options; +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 + } + } +} - 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 - }; - options.env = getEnv(options); +/***/ }), +/* 235 */ +/***/ (function(module, exports, __webpack_require__) { - options.stdio = normalizeStdio(options); +module.exports = isexe +isexe.sync = sync - if (process.platform === 'win32' && path.basename(file, '.exe') === 'cmd') { - // #116 - args.unshift('/q'); - } +var fs = __webpack_require__(134) - return {file, args, options, parsed}; -}; +function checkPathExt (path, options) { + var pathext = options.pathExt !== undefined ? + options.pathExt : process.env.PATHEXT -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 (!pathext) { + return true + } - if (options.stripFinalNewline) { - return stripFinalNewline(value); - } + 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 +} - return value; -}; +function checkStat (stat, path, options) { + if (!stat.isSymbolicLink() && !stat.isFile()) { + return false + } + return checkPathExt(path, options) +} -const execa = (file, args, options) => { - const parsed = handleArgs(file, args, options); - const command = joinCommand(file, args); +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, path, options)) + }) +} - 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); - } +function sync (path, options) { + return checkStat(fs.statSync(path), path, options) +} - const spawnedPromise = getSpawnedPromise(spawned); - const timedPromise = setupTimeout(spawned, parsed.options, spawnedPromise); - const processDone = setExitHandler(spawned, parsed.options, timedPromise); - const context = {isCanceled: false}; +/***/ }), +/* 236 */ +/***/ (function(module, exports, __webpack_require__) { - spawned.kill = spawnedKill.bind(null, spawned.kill.bind(spawned)); - spawned.cancel = spawnedCancel.bind(null, spawned, context); +module.exports = isexe +isexe.sync = sync - 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); +var fs = __webpack_require__(134) - if (error || exitCode !== 0 || signal !== null) { - const returnedError = makeError({ - error, - exitCode, - signal, - stdout, - stderr, - all, - command, - parsed, - timedOut, - isCanceled: context.isCanceled, - killed: spawned.killed - }); +function isexe (path, options, cb) { + fs.stat(path, function (er, stat) { + cb(er, er ? false : checkStat(stat, options)) + }) +} - if (!parsed.options.reject) { - return returnedError; - } +function sync (path, options) { + return checkStat(fs.statSync(path), options) +} - throw returnedError; - } +function checkStat (stat, options) { + return stat.isFile() && checkMode(stat, options) +} - return { - command, - exitCode: 0, - stdout, - stderr, - all, - failed: false, - timedOut: false, - isCanceled: false, - killed: false - }; - }; +function checkMode (stat, options) { + var mod = stat.mode + var uid = stat.uid + var gid = stat.gid - const handlePromiseOnce = onetime(handlePromise); + var myUid = options.uid !== undefined ? + options.uid : process.getuid && process.getuid() + var myGid = options.gid !== undefined ? + options.gid : process.getgid && process.getgid() - crossSpawn._enoent.hookChildProcess(spawned, parsed.parsed); + var u = parseInt('100', 8) + var g = parseInt('010', 8) + var o = parseInt('001', 8) + var ug = u | g - handleInput(spawned, parsed.options.input); + var ret = (mod & o) || + (mod & g) && gid === myGid || + (mod & u) && uid === myUid || + (mod & ug) && myUid === 0 - spawned.all = makeAllStream(spawned, parsed.options); + return ret +} - return mergePromise(spawned, handlePromiseOnce); -}; -module.exports = execa; +/***/ }), +/* 237 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports.sync = (file, args, options) => { - const parsed = handleArgs(file, args, options); - const command = joinCommand(file, args); +"use strict"; - 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 pathKey = (options = {}) => { + const environment = options.env || process.env; + const platform = options.platform || process.platform; + + if (platform !== 'win32') { + return 'PATH'; } - const stdout = handleOutput(parsed.options, result.stdout, result.error); - const stderr = handleOutput(parsed.options, result.stderr, result.error); + return Object.keys(environment).find(key => key.toUpperCase() === 'PATH') || 'Path'; +}; - 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 - }); +module.exports = pathKey; +// TODO: Remove this for the next major release +module.exports.default = pathKey; - if (!parsed.options.reject) { - return error; - } - throw error; - } +/***/ }), +/* 238 */ +/***/ (function(module, exports, __webpack_require__) { - return { - command, - exitCode: 0, - stdout, - stderr, - failed: false, - timedOut: false, - isCanceled: false, - killed: false - }; -}; +"use strict"; -module.exports.command = (command, options) => { - const [file, ...args] = parseCommand(command); - return execa(file, args, options); -}; -module.exports.commandSync = (command, options) => { - const [file, ...args] = parseCommand(command); - return execa.sync(file, args, options); -}; +// See http://www.robvanderwoude.com/escapechars.php +const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; -module.exports.node = (scriptPath, args, options = {}) => { - if (args && !Array.isArray(args) && typeof args === 'object') { - options = args; - args = []; - } +function escapeCommand(arg) { + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); - const stdio = normalizeStdio.node(options); + return arg; +} - const {nodePath = process.execPath, nodeOptions = process.execArgv} = options; +function escapeArgument(arg, doubleEscapeMetaChars) { + // Convert to string + arg = `${arg}`; - return execa( - nodePath, - [ - ...nodeOptions, - scriptPath, - ...(Array.isArray(args) ? args : []) - ], - { - ...options, - stdin: undefined, - stdout: undefined, - stderr: undefined, - stdio, - shell: false - } - ); -}; + // Algorithm below is based on https://qntm.org/cmd + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(\\*)"/g, '$1$1\\"'); -/***/ }), -/* 233 */ -/***/ (function(module, exports) { + // 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'); + + // All other backslashes occur literally + + // Quote the whole thing: + arg = `"${arg}"`; + + // Escape meta chars + arg = arg.replace(metaCharsRegExp, '^$1'); + + // Double escape meta chars if necessary + if (doubleEscapeMetaChars) { + arg = arg.replace(metaCharsRegExp, '^$1'); + } + + return arg; +} + +module.exports.command = escapeCommand; +module.exports.argument = escapeArgument; -module.exports = require("child_process"); /***/ }), -/* 234 */ +/* 239 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const cp = __webpack_require__(233); -const parse = __webpack_require__(235); -const enoent = __webpack_require__(246); +const fs = __webpack_require__(134); +const shebangCommand = __webpack_require__(240); -function spawn(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); +function readShebang(command) { + // Read the first 150 bytes from the file + const size = 150; + const buffer = Buffer.alloc(size); - // Spawn the child process - const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + let fd; - // 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); + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, size, 0); + fs.closeSync(fd); + } catch (e) { /* Empty */ } - return spawned; + // Attempt to extract shebang (null is returned if not a shebang) + return shebangCommand(buffer.toString()); } -function spawnSync(command, args, options) { - // Parse the arguments - const parsed = parse(command, args, options); +module.exports = readShebang; - // Spawn the child process - const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); - // 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); +/***/ }), +/* 240 */ +/***/ (function(module, exports, __webpack_require__) { - return result; -} +"use strict"; -module.exports = spawn; -module.exports.spawn = spawn; -module.exports.sync = spawnSync; +const shebangRegex = __webpack_require__(241); -module.exports._parse = parse; -module.exports._enoent = enoent; +module.exports = (string = '') => { + const match = string.match(shebangRegex); + + if (!match) { + return null; + } + + const [path, argument] = match[0].replace(/#! ?/, '').split(' '); + const binary = path.split('/').pop(); + + if (binary === 'env') { + return argument; + } + + return argument ? `${binary} ${argument}` : binary; +}; /***/ }), -/* 235 */ +/* 241 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +module.exports = /^#!(.*)/; -const path = __webpack_require__(4); -const resolveCommand = __webpack_require__(236); -const escape = __webpack_require__(242); -const readShebang = __webpack_require__(243); - -const isWin = process.platform === 'win32'; -const isExecutableRegExp = /\.(?:com|exe)$/i; -const isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i; -function detectShebang(parsed) { - parsed.file = resolveCommand(parsed); +/***/ }), +/* 242 */ +/***/ (function(module, exports, __webpack_require__) { - const shebang = parsed.file && readShebang(parsed.file); +"use strict"; - if (shebang) { - parsed.args.unshift(parsed.file); - parsed.command = shebang; - return resolveCommand(parsed); - } +const isWin = process.platform === 'win32'; - return parsed.file; +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 parseNonShell(parsed) { +function hookChildProcess(cp, parsed) { if (!isWin) { - return parsed; + return; } - // Detect & add support for shebangs - const commandFile = detectShebang(parsed); - - // We don't need a shell if the command filename is an executable - const needsShell = !isExecutableRegExp.test(commandFile); - - // 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 originalEmit = cp.emit; - // 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); + 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'); - // Escape command & arguments - parsed.command = escape.command(parsed.command); - parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars)); + if (err) { + return originalEmit.call(cp, 'error', err); + } + } - const shellCommand = [parsed.command].concat(parsed.args).join(' '); + return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params + }; +} - 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 +function verifyENOENT(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); } - return parsed; + return null; } -function parse(command, args, options) { - // Normalize arguments, similar to nodejs - if (args && !Array.isArray(args)) { - options = args; - args = null; +function verifyENOENTSync(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); } - 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); + return null; } -module.exports = parse; +module.exports = { + hookChildProcess, + verifyENOENT, + verifyENOENTSync, + notFoundError, +}; /***/ }), -/* 236 */ +/* 243 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const path = __webpack_require__(4); -const which = __webpack_require__(237); -const pathKey = __webpack_require__(241)(); +module.exports = input => { + const LF = typeof input === 'string' ? '\n' : '\n'.charCodeAt(); + const CR = typeof input === 'string' ? '\r' : '\r'.charCodeAt(); -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; + if (input[input.length - 1] === LF) { + input = input.slice(0, input.length - 1); + } - // 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 */ - } - } + if (input[input.length - 1] === CR) { + input = input.slice(0, input.length - 1); + } - let resolved; + return input; +}; - 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); - } - } - // 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); - } +/***/ }), +/* 244 */ +/***/ (function(module, exports, __webpack_require__) { - return resolved; -} +"use strict"; -function resolveCommand(parsed) { - return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true); -} +const path = __webpack_require__(4); +const pathKey = __webpack_require__(237); -module.exports = resolveCommand; +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 = []; -/***/ }), -/* 237 */ -/***/ (function(module, exports, __webpack_require__) { + while (previous !== cwdPath) { + result.push(path.join(cwdPath, 'node_modules/.bin')); + previous = cwdPath; + cwdPath = path.resolve(cwdPath, '..'); + } -const isWindows = process.platform === 'win32' || - process.env.OSTYPE === 'cygwin' || - process.env.OSTYPE === 'msys' + // Ensure the running `node` binary is used + const execPathDir = path.resolve(options.cwd, options.execPath, '..'); + result.push(execPathDir); -const path = __webpack_require__(4) -const COLON = isWindows ? ';' : ':' -const isexe = __webpack_require__(238) + return result.concat(options.path).join(path.delimiter); +}; -const getNotFoundError = (cmd) => - Object.assign(new Error(`not found: ${cmd}`), { code: 'ENOENT' }) +module.exports = npmRunPath; +// TODO: Remove this for the next major release +module.exports.default = npmRunPath; -const getPathInfo = (cmd, opt) => { - const colon = opt.colon || COLON +module.exports.env = options => { + options = { + env: process.env, + ...options + }; - // 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) : [''] + const env = {...options.env}; + const path = pathKey({env}); - if (isWindows) { - if (cmd.indexOf('.') !== -1 && pathExt[0] !== '') - pathExt.unshift('') - } + options.path = env[path]; + env[path] = module.exports(options); - return { - pathEnv, - pathExt, - pathExtExe, - } -} + return env; +}; -const which = (cmd, opt, cb) => { - if (typeof opt === 'function') { - cb = opt - opt = {} - } - if (!opt) - opt = {} - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] +/***/ }), +/* 245 */ +/***/ (function(module, exports, __webpack_require__) { - const step = i => new Promise((resolve, reject) => { - if (i === pathEnv.length) - return opt.all && found.length ? resolve(found) - : reject(getNotFoundError(cmd)) +"use strict"; - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw +const mimicFn = __webpack_require__(246); - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd +const calledFunctions = new WeakMap(); - resolve(subStep(p, i, 0)) - }) +const oneTime = (fn, options = {}) => { + if (typeof fn !== 'function') { + throw new TypeError('Expected a function'); + } - 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)) - }) - }) + let ret; + let isCalled = false; + let callCount = 0; + const functionName = fn.displayName || fn.name || ''; - return cb ? step(0).then(res => cb(null, res), cb) : step(0) -} + const onetime = function (...args) { + calledFunctions.set(onetime, ++callCount); -const whichSync = (cmd, opt) => { - opt = opt || {} + if (isCalled) { + if (options.throw === true) { + throw new Error(`Function \`${functionName}\` can only be called once`); + } - const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt) - const found = [] + return ret; + } - for (let i = 0; i < pathEnv.length; i ++) { - const ppRaw = pathEnv[i] - const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw + isCalled = true; + ret = fn.apply(this, args); + fn = null; - const pCmd = path.join(pathPart, cmd) - const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd - : pCmd + return ret; + }; - 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) {} - } - } + mimicFn(onetime, fn); + calledFunctions.set(onetime, callCount); - if (opt.all && found.length) - return found + return onetime; +}; - if (opt.nothrow) - return null +module.exports = oneTime; +// TODO: Remove this for the next major release +module.exports.default = oneTime; - throw getNotFoundError(cmd) -} +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 = which -which.sync = whichSync + return calledFunctions.get(fn); +}; /***/ }), -/* 238 */ +/* 246 */ /***/ (function(module, exports, __webpack_require__) { -var fs = __webpack_require__(133) -var core -if (process.platform === 'win32' || global.TESTING_WINDOWS) { - core = __webpack_require__(239) -} else { - core = __webpack_require__(240) -} - -module.exports = isexe -isexe.sync = sync - -function isexe (path, options, cb) { - if (typeof options === 'function') { - cb = options - options = {} - } +"use strict"; - if (!cb) { - if (typeof Promise !== 'function') { - throw new TypeError('callback not provided') - } - return new Promise(function (resolve, reject) { - isexe(path, options || {}, function (er, is) { - if (er) { - reject(er) - } else { - resolve(is) - } - }) - }) - } +const mimicFn = (to, from) => { + for (const prop of Reflect.ownKeys(from)) { + Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); + } - 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 to; +}; -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 - } - } -} +module.exports = mimicFn; +// TODO: Remove this for the next major release +module.exports.default = mimicFn; /***/ }), -/* 239 */ +/* 247 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = isexe -isexe.sync = sync - -var fs = __webpack_require__(133) - -function checkPathExt (path, options) { - var pathext = options.pathExt !== undefined ? - options.pathExt : process.env.PATHEXT +"use strict"; - if (!pathext) { - return true - } +const {signalsByName} = __webpack_require__(248); - 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 -} +const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { + if (timedOut) { + return `timed out after ${timeout} milliseconds`; + } -function checkStat (stat, path, options) { - if (!stat.isSymbolicLink() && !stat.isFile()) { - return false - } - return checkPathExt(path, options) -} + if (isCanceled) { + return 'was canceled'; + } -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, path, options)) - }) -} + if (errorCode !== undefined) { + return `failed with ${errorCode}`; + } -function sync (path, options) { - return checkStat(fs.statSync(path), path, options) -} + if (signal !== undefined) { + return `was killed with ${signal} (${signalDescription})`; + } + if (exitCode !== undefined) { + return `failed with exit code ${exitCode}`; + } -/***/ }), -/* 240 */ -/***/ (function(module, exports, __webpack_require__) { + return 'failed'; +}; -module.exports = isexe -isexe.sync = sync +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; -var fs = __webpack_require__(133) + const errorCode = error && error.code; -function isexe (path, options, cb) { - fs.stat(path, function (er, stat) { - cb(er, er ? false : checkStat(stat, options)) - }) -} + 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'); -function sync (path, options) { - return checkStat(fs.statSync(path), options) -} + if (isError) { + error.originalMessage = error.message; + error.message = message; + } else { + error = new Error(message); + } -function checkStat (stat, options) { - return stat.isFile() && checkMode(stat, options) -} + error.shortMessage = shortMessage; + error.command = command; + error.exitCode = exitCode; + error.signal = signal; + error.signalDescription = signalDescription; + error.stdout = stdout; + error.stderr = stderr; -function checkMode (stat, options) { - var mod = stat.mode - var uid = stat.uid - var gid = stat.gid + if (all !== undefined) { + error.all = all; + } - var myUid = options.uid !== undefined ? - options.uid : process.getuid && process.getuid() - var myGid = options.gid !== undefined ? - options.gid : process.getgid && process.getgid() + if ('bufferedData' in error) { + delete error.bufferedData; + } - var u = parseInt('100', 8) - var g = parseInt('010', 8) - var o = parseInt('001', 8) - var ug = u | g + error.failed = true; + error.timedOut = Boolean(timedOut); + error.isCanceled = isCanceled; + error.killed = killed && !timedOut; - var ret = (mod & o) || - (mod & g) && gid === myGid || - (mod & u) && uid === myUid || - (mod & ug) && myUid === 0 + return error; +}; - return ret -} +module.exports = makeError; /***/ }), -/* 241 */ +/* 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); +var _signals=__webpack_require__(249); +var _realtime=__webpack_require__(251); -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'; +const getSignalsByName=function(){ +const signals=(0,_signals.getSignals)(); +return signals.reduce(getSignalByName,{}); }; -module.exports = pathKey; -// TODO: Remove this for the next major release -module.exports.default = pathKey; +const getSignalByName=function( +signalByNameMemo, +{name,number,description,supported,action,forced,standard}) +{ +return{ +...signalByNameMemo, +[name]:{name,number,description,supported,action,forced,standard}}; +}; -/***/ }), -/* 242 */ -/***/ (function(module, exports, __webpack_require__) { +const signalsByName=getSignalsByName();exports.signalsByName=signalsByName; -"use strict"; -// See http://www.robvanderwoude.com/escapechars.php -const metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g; -function escapeCommand(arg) { - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); +const getSignalsByNumber=function(){ +const signals=(0,_signals.getSignals)(); +const length=_realtime.SIGRTMAX+1; +const signalsA=Array.from({length},(value,number)=> +getSignalByNumber(number,signals)); - return arg; -} +return Object.assign({},...signalsA); +}; -function escapeArgument(arg, doubleEscapeMetaChars) { - // Convert to string - arg = `${arg}`; +const getSignalByNumber=function(number,signals){ +const signal=findSignalByNumber(number,signals); - // Algorithm below is based on https://qntm.org/cmd +if(signal===undefined){ +return{}; +} - // Sequence of backslashes followed by a double quote: - // double up all the backslashes and escape the double quote - arg = arg.replace(/(\\*)"/g, '$1$1\\"'); +const{name,description,supported,action,forced,standard}=signal; +return{ +[number]:{ +name, +number, +description, +supported, +action, +forced, +standard}}; - // 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'); - // All other backslashes occur literally - - // Quote the whole thing: - arg = `"${arg}"`; - - // Escape meta chars - arg = arg.replace(metaCharsRegExp, '^$1'); - - // Double escape meta chars if necessary - if (doubleEscapeMetaChars) { - arg = arg.replace(metaCharsRegExp, '^$1'); - } - - return arg; -} - -module.exports.command = escapeCommand; -module.exports.argument = escapeArgument; - - -/***/ }), -/* 243 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -const fs = __webpack_require__(133); -const shebangCommand = __webpack_require__(244); - -function readShebang(command) { - // Read the first 150 bytes from the file - const size = 150; - const buffer = Buffer.alloc(size); - - let fd; - - try { - fd = fs.openSync(command, 'r'); - fs.readSync(fd, buffer, 0, size, 0); - fs.closeSync(fd); - } catch (e) { /* Empty */ } - - // Attempt to extract shebang (null is returned if not a shebang) - return shebangCommand(buffer.toString()); -} - -module.exports = readShebang; - - -/***/ }), -/* 244 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const shebangRegex = __webpack_require__(245); - -module.exports = (string = '') => { - const match = string.match(shebangRegex); - - if (!match) { - return null; - } - - const [path, argument] = match[0].replace(/#! ?/, '').split(' '); - const binary = path.split('/').pop(); - - if (binary === 'env') { - return argument; - } - - return argument ? `${binary} ${argument}` : binary; -}; - - -/***/ }), -/* 245 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -module.exports = /^#!(.*)/; - - -/***/ }), -/* 246 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -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'); - - if (err) { - return originalEmit.call(cp, 'error', err); - } - } - - return originalEmit.apply(cp, arguments); // eslint-disable-line prefer-rest-params - }; -} - -function verifyENOENT(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawn'); - } - - return null; -} - -function verifyENOENTSync(status, parsed) { - if (isWin && status === 1 && !parsed.file) { - return notFoundError(parsed.original, 'spawnSync'); - } - - return null; -} - -module.exports = { - hookChildProcess, - verifyENOENT, - verifyENOENTSync, - notFoundError, -}; - - -/***/ }), -/* 247 */ -/***/ (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); - } - - return input; -}; - - -/***/ }), -/* 248 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const path = __webpack_require__(4); -const pathKey = __webpack_require__(241); - -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 = []; - - while (previous !== cwdPath) { - result.push(path.join(cwdPath, 'node_modules/.bin')); - previous = cwdPath; - cwdPath = path.resolve(cwdPath, '..'); - } - - // Ensure the running `node` binary is used - const execPathDir = path.resolve(options.cwd, options.execPath, '..'); - result.push(execPathDir); - - return result.concat(options.path).join(path.delimiter); -}; - -module.exports = npmRunPath; -// TODO: Remove this for the next major release -module.exports.default = npmRunPath; - -module.exports.env = options => { - options = { - env: process.env, - ...options - }; - - const env = {...options.env}; - const path = pathKey({env}); - - options.path = env[path]; - env[path] = module.exports(options); - - return env; -}; - - -/***/ }), -/* 249 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const mimicFn = __webpack_require__(250); - -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; - } - - isCalled = true; - ret = fn.apply(this, args); - fn = null; - - return ret; - }; - - 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`); - } - - return calledFunctions.get(fn); -}; - - -/***/ }), -/* 250 */ -/***/ (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)); - } - - return to; -}; - -module.exports = mimicFn; -// TODO: Remove this for the next major release -module.exports.default = mimicFn; - - -/***/ }), -/* 251 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const {signalsByName} = __webpack_require__(252); - -const getErrorPrefix = ({timedOut, timeout, errorCode, signal, signalDescription, exitCode, isCanceled}) => { - if (timedOut) { - return `timed out after ${timeout} milliseconds`; - } - - if (isCanceled) { - return 'was canceled'; - } - - if (errorCode !== undefined) { - return `failed with ${errorCode}`; - } - - if (signal !== undefined) { - return `was killed with ${signal} (${signalDescription})`; - } - - if (exitCode !== undefined) { - return `failed with exit code ${exitCode}`; - } - - return 'failed'; -}; - -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; - - const errorCode = error && error.code; - - 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 (isError) { - error.originalMessage = error.message; - error.message = message; - } else { - error = new Error(message); - } - - error.shortMessage = shortMessage; - error.command = command; - error.exitCode = exitCode; - error.signal = signal; - error.signalDescription = signalDescription; - error.stdout = stdout; - error.stderr = stderr; - - if (all !== undefined) { - error.all = all; - } - - if ('bufferedData' in error) { - delete error.bufferedData; - } - - error.failed = true; - error.timedOut = Boolean(timedOut); - error.isCanceled = isCanceled; - error.killed = killed && !timedOut; - - return error; -}; - -module.exports = makeError; - - -/***/ }), -/* 252 */ -/***/ (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__(253); -var _realtime=__webpack_require__(255); - - - -const getSignalsByName=function(){ -const signals=(0,_signals.getSignals)(); -return signals.reduce(getSignalByName,{}); -}; - -const getSignalByName=function( -signalByNameMemo, -{name,number,description,supported,action,forced,standard}) -{ -return{ -...signalByNameMemo, -[name]:{name,number,description,supported,action,forced,standard}}; - -}; - -const signalsByName=getSignalsByName();exports.signalsByName=signalsByName; - - - - -const getSignalsByNumber=function(){ -const signals=(0,_signals.getSignals)(); -const length=_realtime.SIGRTMAX+1; -const signalsA=Array.from({length},(value,number)=> -getSignalByNumber(number,signals)); - -return Object.assign({},...signalsA); -}; - -const getSignalByNumber=function(number,signals){ -const signal=findSignalByNumber(number,signals); - -if(signal===undefined){ -return{}; -} - -const{name,description,supported,action,forced,standard}=signal; -return{ -[number]:{ -name, -number, -description, -supported, -action, -forced, -standard}}; - - -}; +}; @@ -25612,14 +25166,14 @@ const signalsByNumber=getSignalsByNumber();exports.signalsByNumber=signalsByNumb //# sourceMappingURL=main.js.map /***/ }), -/* 253 */ +/* 249 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(120); +Object.defineProperty(exports,"__esModule",{value:true});exports.getSignals=void 0;var _os=__webpack_require__(121); -var _core=__webpack_require__(254); -var _realtime=__webpack_require__(255); +var _core=__webpack_require__(250); +var _realtime=__webpack_require__(251); @@ -25653,7 +25207,7 @@ return{name,number,description,supported,action,forced,standard}; //# sourceMappingURL=signals.js.map /***/ }), -/* 254 */ +/* 250 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -25932,7 +25486,7 @@ standard:"other"}];exports.SIGNALS=SIGNALS; //# sourceMappingURL=core.js.map /***/ }), -/* 255 */ +/* 251 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -25957,7 +25511,7 @@ const SIGRTMAX=64;exports.SIGRTMAX=SIGRTMAX; //# sourceMappingURL=realtime.js.map /***/ }), -/* 256 */ +/* 252 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -26016,13 +25570,13 @@ module.exports.node = opts => { /***/ }), -/* 257 */ +/* 253 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(120); -const onExit = __webpack_require__(217); +const os = __webpack_require__(121); +const onExit = __webpack_require__(218); const DEFAULT_FORCE_KILL_TIMEOUT = 1000 * 5; @@ -26066,7 +25620,7 @@ const getForceKillAfterTimeout = ({forceKillAfterTimeout = true}) => { return DEFAULT_FORCE_KILL_TIMEOUT; } - if (!Number.isInteger(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { + if (!Number.isFinite(forceKillAfterTimeout) || forceKillAfterTimeout < 0) { throw new TypeError(`Expected the \`forceKillAfterTimeout\` option to be a non-negative integer, got \`${forceKillAfterTimeout}\` (${typeof forceKillAfterTimeout})`); } @@ -26093,7 +25647,7 @@ const setupTimeout = (spawned, {timeout, killSignal = 'SIGTERM'}, spawnedPromise return spawnedPromise; } - if (!Number.isInteger(timeout) || timeout < 0) { + if (!Number.isFinite(timeout) || timeout < 0) { throw new TypeError(`Expected the \`timeout\` option to be a non-negative integer, got \`${timeout}\` (${typeof timeout})`); } @@ -26135,14 +25689,14 @@ module.exports = { /***/ }), -/* 258 */ +/* 254 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const isStream = __webpack_require__(259); -const getStream = __webpack_require__(260); -const mergeStream = __webpack_require__(264); +const isStream = __webpack_require__(255); +const getStream = __webpack_require__(256); +const mergeStream = __webpack_require__(260); // `input` option const handleInput = (spawned, input) => { @@ -26239,7 +25793,7 @@ module.exports = { /***/ }), -/* 259 */ +/* 255 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -26275,13 +25829,13 @@ module.exports = isStream; /***/ }), -/* 260 */ +/* 256 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pump = __webpack_require__(261); -const bufferStream = __webpack_require__(263); +const pump = __webpack_require__(257); +const bufferStream = __webpack_require__(259); class MaxBufferError extends Error { constructor() { @@ -26340,12 +25894,12 @@ module.exports.MaxBufferError = MaxBufferError; /***/ }), -/* 261 */ +/* 257 */ /***/ (function(module, exports, __webpack_require__) { -var once = __webpack_require__(161) -var eos = __webpack_require__(262) -var fs = __webpack_require__(133) // we only need fs to get the ReadStream and WriteStream prototypes +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 var noop = function () {} var ancient = /^v?\.0/.test(process.version) @@ -26428,10 +25982,10 @@ module.exports = pump /***/ }), -/* 262 */ +/* 258 */ /***/ (function(module, exports, __webpack_require__) { -var once = __webpack_require__(161); +var once = __webpack_require__(162); var noop = function() {}; @@ -26528,12 +26082,12 @@ module.exports = eos; /***/ }), -/* 263 */ +/* 259 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {PassThrough: PassThroughStream} = __webpack_require__(137); +const {PassThrough: PassThroughStream} = __webpack_require__(138); module.exports = options => { options = {...options}; @@ -26587,13 +26141,13 @@ module.exports = options => { /***/ }), -/* 264 */ +/* 260 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const { PassThrough } = __webpack_require__(137); +const { PassThrough } = __webpack_require__(138); module.exports = function (/*streams...*/) { var sources = [] @@ -26635,7 +26189,7 @@ module.exports = function (/*streams...*/) { /***/ }), -/* 265 */ +/* 261 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -26688,7 +26242,7 @@ module.exports = { /***/ }), -/* 266 */ +/* 262 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -26733,7 +26287,7 @@ module.exports = { /***/ }), -/* 267 */ +/* 263 */ /***/ (function(module, exports, __webpack_require__) { // Copyright IBM Corp. 2014,2018. All Rights Reserved. @@ -26741,12 +26295,12 @@ module.exports = { // This file is licensed under the Apache License 2.0. // License text available at https://opensource.org/licenses/Apache-2.0 -module.exports = __webpack_require__(268); -module.exports.cli = __webpack_require__(272); +module.exports = __webpack_require__(264); +module.exports.cli = __webpack_require__(268); /***/ }), -/* 268 */ +/* 264 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -26757,13 +26311,13 @@ module.exports.cli = __webpack_require__(272); -var stream = __webpack_require__(137); -var util = __webpack_require__(111); -var fs = __webpack_require__(133); +var stream = __webpack_require__(138); +var util = __webpack_require__(112); +var fs = __webpack_require__(134); -var through = __webpack_require__(269); -var duplexer = __webpack_require__(270); -var StringDecoder = __webpack_require__(271).StringDecoder; +var through = __webpack_require__(265); +var duplexer = __webpack_require__(266); +var StringDecoder = __webpack_require__(267).StringDecoder; module.exports = Logger; @@ -26952,10 +26506,10 @@ function lineMerger(host) { /***/ }), -/* 269 */ +/* 265 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(137) +var Stream = __webpack_require__(138) // through // @@ -27066,10 +26620,10 @@ function through (write, end, opts) { /***/ }), -/* 270 */ +/* 266 */ /***/ (function(module, exports, __webpack_require__) { -var Stream = __webpack_require__(137) +var Stream = __webpack_require__(138) var writeMethods = ["write", "end", "destroy"] var readMethods = ["resume", "pause"] var readEvents = ["data", "close"] @@ -27159,13 +26713,13 @@ function duplex(writer, reader) { /***/ }), -/* 271 */ +/* 267 */ /***/ (function(module, exports) { module.exports = require("string_decoder"); /***/ }), -/* 272 */ +/* 268 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -27176,11 +26730,11 @@ module.exports = require("string_decoder"); -var minimist = __webpack_require__(273); +var minimist = __webpack_require__(269); var path = __webpack_require__(4); -var Logger = __webpack_require__(268); -var pkg = __webpack_require__(274); +var Logger = __webpack_require__(264); +var pkg = __webpack_require__(270); module.exports = cli; @@ -27234,7 +26788,7 @@ function usage($0, p) { /***/ }), -/* 273 */ +/* 269 */ /***/ (function(module, exports) { module.exports = function (args, opts) { @@ -27485,29 +27039,29 @@ function isNumber (x) { /***/ }), -/* 274 */ +/* 270 */ /***/ (function(module) { 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\"}}"); /***/ }), -/* 275 */ +/* 271 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "workspacePackagePaths", function() { return workspacePackagePaths; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyWorkspacePackages", function() { return copyWorkspacePackages; }); -/* harmony import */ var glob__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(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 _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(276); -/* 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); +/* 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 @@ -27599,7 +27153,7 @@ function packagesFromGlobPattern({ } /***/ }), -/* 276 */ +/* 272 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -27669,21 +27223,21 @@ function getProjectPaths({ } /***/ }), -/* 277 */ +/* 273 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "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__ = __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__(278); +/* 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__(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 execa__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(232); +/* 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__(279); +/* 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 @@ -27882,22 +27436,22 @@ async function getAllChecksums(kbn, log, yarnLock) { } /***/ }), -/* 278 */ +/* 274 */ /***/ (function(module, exports) { module.exports = require("crypto"); /***/ }), -/* 279 */ +/* 275 */ /***/ (function(module, __webpack_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__(280); +/* 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__(130); +/* 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 @@ -28008,7 +27562,7 @@ function resolveDepsForProject({ } /***/ }), -/* 280 */ +/* 276 */ /***/ (function(module, exports, __webpack_require__) { module.exports = @@ -28134,13 +27688,13 @@ exports.default = function (fn) { /* 2 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(111); +module.exports = __webpack_require__(112); /***/ }), /* 3 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(133); +module.exports = __webpack_require__(134); /***/ }), /* 4 */ @@ -29567,7 +29121,7 @@ module.exports = invariant; /* 9 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(278); +module.exports = __webpack_require__(274); /***/ }), /* 10 */, @@ -29993,7 +29547,7 @@ exports.default = Lockfile; /* 17 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(137); +module.exports = __webpack_require__(138); /***/ }), /* 18 */, @@ -30045,7 +29599,7 @@ function nullify(obj = {}) { /* 22 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(139); +module.exports = __webpack_require__(140); /***/ }), /* 23 */ @@ -30232,7 +29786,7 @@ module.exports = {}; /* 36 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(120); +module.exports = __webpack_require__(121); /***/ }), /* 37 */, @@ -30517,7 +30071,7 @@ exports.f = __webpack_require__(33) ? Object.defineProperty : function definePro /* 54 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(155); +module.exports = __webpack_require__(156); /***/ }), /* 55 */ @@ -31891,7 +31445,7 @@ function onceStrict (fn) { /* 63 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(281); +module.exports = __webpack_require__(277); /***/ }), /* 64 */, @@ -32829,7 +32383,7 @@ module.exports.win32 = win32; /* 79 */ /***/ (function(module, exports) { -module.exports = __webpack_require__(121); +module.exports = __webpack_require__(122); /***/ }), /* 80 */, @@ -38286,19 +37840,19 @@ module.exports = process && support(supportLevel); /******/ ]); /***/ }), -/* 281 */ +/* 277 */ /***/ (function(module, exports) { module.exports = require("buffer"); /***/ }), -/* 282 */ +/* 278 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "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__ = __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__); @@ -38389,18 +37943,18 @@ class BootstrapCacheFile { } /***/ }), -/* 283 */ +/* 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__(280); +/* 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__(130); -/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(143); +/* 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 @@ -38490,26 +38044,78 @@ async function validateYarnLock(kbn, 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, [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` + + [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__WEBPACK_IMPORTED_MODULE_3__["log"].success('yarn.lock analysis completed without any issues'); } /***/ }), -/* 284 */ +/* 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__(285); +/* 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__(372); +/* 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__(130); -/* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(143); +/* 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 @@ -38604,21 +38210,21 @@ const CleanCommand = { }; /***/ }), -/* 285 */ +/* 281 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {promisify} = __webpack_require__(111); +const {promisify} = __webpack_require__(112); const path = __webpack_require__(4); -const globby = __webpack_require__(286); -const isGlob = __webpack_require__(364); -const slash = __webpack_require__(362); -const gracefulFs = __webpack_require__(132); -const isPathCwd = __webpack_require__(365); -const isPathInside = __webpack_require__(366); -const rimraf = __webpack_require__(367); -const pMap = __webpack_require__(368); +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); const rimrafP = promisify(rimraf); @@ -38732,19 +38338,19 @@ module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options /***/ }), -/* 286 */ +/* 282 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(133); -const arrayUnion = __webpack_require__(287); -const merge2 = __webpack_require__(288); -const glob = __webpack_require__(146); -const fastGlob = __webpack_require__(289); -const dirGlob = __webpack_require__(358); -const gitignore = __webpack_require__(360); -const {FilterStream, UniqueStream} = __webpack_require__(363); +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); const DEFAULT_FILTER = () => false; @@ -38917,7 +38523,7 @@ module.exports.gitignore = gitignore; /***/ }), -/* 287 */ +/* 283 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -38929,7 +38535,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 288 */ +/* 284 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -38941,7 +38547,7 @@ module.exports = (...arguments_) => { * Copyright (c) 2014-2020 Teambition * Licensed under the MIT license. */ -const Stream = __webpack_require__(137) +const Stream = __webpack_require__(138) const PassThrough = Stream.PassThrough const slice = Array.prototype.slice @@ -39080,17 +38686,17 @@ function pauseStreams (streams, options) { /***/ }), -/* 289 */ +/* 285 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const taskManager = __webpack_require__(290); -const async_1 = __webpack_require__(319); -const stream_1 = __webpack_require__(354); -const sync_1 = __webpack_require__(355); -const settings_1 = __webpack_require__(357); -const utils = __webpack_require__(291); +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); @@ -39154,13 +38760,13 @@ module.exports = FastGlob; /***/ }), -/* 290 */ +/* 286 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(291); +const utils = __webpack_require__(287); function generate(patterns, settings) { const positivePatterns = getPositivePatterns(patterns); const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); @@ -39225,30 +38831,30 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 291 */ +/* 287 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const array = __webpack_require__(292); +const array = __webpack_require__(288); exports.array = array; -const errno = __webpack_require__(293); +const errno = __webpack_require__(289); exports.errno = errno; -const fs = __webpack_require__(294); +const fs = __webpack_require__(290); exports.fs = fs; -const path = __webpack_require__(295); +const path = __webpack_require__(291); exports.path = path; -const pattern = __webpack_require__(296); +const pattern = __webpack_require__(292); exports.pattern = pattern; -const stream = __webpack_require__(317); +const stream = __webpack_require__(313); exports.stream = stream; -const string = __webpack_require__(318); +const string = __webpack_require__(314); exports.string = string; /***/ }), -/* 292 */ +/* 288 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -39276,7 +38882,7 @@ exports.splitWhen = splitWhen; /***/ }), -/* 293 */ +/* 289 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -39289,7 +38895,7 @@ exports.isEnoentCodeError = isEnoentCodeError; /***/ }), -/* 294 */ +/* 290 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -39314,7 +38920,7 @@ exports.createDirentFromStats = createDirentFromStats; /***/ }), -/* 295 */ +/* 291 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -39353,16 +38959,16 @@ exports.removeLeadingDotSegment = removeLeadingDotSegment; /***/ }), -/* 296 */ +/* 292 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const globParent = __webpack_require__(297); -const micromatch = __webpack_require__(300); -const picomatch = __webpack_require__(311); +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 = /[*?]|^!/; @@ -39472,15 +39078,15 @@ exports.matchAny = matchAny; /***/ }), -/* 297 */ +/* 293 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isGlob = __webpack_require__(298); +var isGlob = __webpack_require__(294); var pathPosixDirname = __webpack_require__(4).posix.dirname; -var isWin32 = __webpack_require__(120).platform() === 'win32'; +var isWin32 = __webpack_require__(121).platform() === 'win32'; var slash = '/'; var backslash = /\\/g; @@ -39520,7 +39126,7 @@ module.exports = function globParent(str, opts) { /***/ }), -/* 298 */ +/* 294 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -39530,7 +39136,7 @@ module.exports = function globParent(str, opts) { * Released under the MIT License. */ -var isExtglob = __webpack_require__(299); +var isExtglob = __webpack_require__(295); var chars = { '{': '}', '(': ')', '[': ']'}; var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; @@ -39574,7 +39180,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 299 */ +/* 295 */ /***/ (function(module, exports) { /*! @@ -39600,16 +39206,16 @@ module.exports = function isExtglob(str) { /***/ }), -/* 300 */ +/* 296 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const util = __webpack_require__(111); -const braces = __webpack_require__(301); -const picomatch = __webpack_require__(311); -const utils = __webpack_require__(314); +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 === './'); /** @@ -40074,16 +39680,16 @@ module.exports = micromatch; /***/ }), -/* 301 */ +/* 297 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringify = __webpack_require__(302); -const compile = __webpack_require__(304); -const expand = __webpack_require__(308); -const parse = __webpack_require__(309); +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. @@ -40251,13 +39857,13 @@ module.exports = braces; /***/ }), -/* 302 */ +/* 298 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const utils = __webpack_require__(303); +const utils = __webpack_require__(299); module.exports = (ast, options = {}) => { let stringify = (node, parent = {}) => { @@ -40290,7 +39896,7 @@ module.exports = (ast, options = {}) => { /***/ }), -/* 303 */ +/* 299 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40409,14 +40015,14 @@ exports.flatten = (...args) => { /***/ }), -/* 304 */ +/* 300 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(305); -const utils = __webpack_require__(303); +const fill = __webpack_require__(301); +const utils = __webpack_require__(299); const compile = (ast, options = {}) => { let walk = (node, parent = {}) => { @@ -40473,7 +40079,7 @@ module.exports = compile; /***/ }), -/* 305 */ +/* 301 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40486,8 +40092,8 @@ module.exports = compile; -const util = __webpack_require__(111); -const toRegexRange = __webpack_require__(306); +const util = __webpack_require__(112); +const toRegexRange = __webpack_require__(302); const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); @@ -40729,7 +40335,7 @@ module.exports = fill; /***/ }), -/* 306 */ +/* 302 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40742,7 +40348,7 @@ module.exports = fill; -const isNumber = __webpack_require__(307); +const isNumber = __webpack_require__(303); const toRegexRange = (min, max, options) => { if (isNumber(min) === false) { @@ -41024,7 +40630,7 @@ module.exports = toRegexRange; /***/ }), -/* 307 */ +/* 303 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41049,15 +40655,15 @@ module.exports = function(num) { /***/ }), -/* 308 */ +/* 304 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(305); -const stringify = __webpack_require__(302); -const utils = __webpack_require__(303); +const fill = __webpack_require__(301); +const stringify = __webpack_require__(298); +const utils = __webpack_require__(299); const append = (queue = '', stash = '', enclose = false) => { let result = []; @@ -41169,13 +40775,13 @@ module.exports = expand; /***/ }), -/* 309 */ +/* 305 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringify = __webpack_require__(302); +const stringify = __webpack_require__(298); /** * Constants @@ -41197,7 +40803,7 @@ const { CHAR_SINGLE_QUOTE, /* ' */ CHAR_NO_BREAK_SPACE, CHAR_ZERO_WIDTH_NOBREAK_SPACE -} = __webpack_require__(310); +} = __webpack_require__(306); /** * parse @@ -41509,7 +41115,7 @@ module.exports = parse; /***/ }), -/* 310 */ +/* 306 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41573,27 +41179,27 @@ module.exports = { /***/ }), -/* 311 */ +/* 307 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = __webpack_require__(312); +module.exports = __webpack_require__(308); /***/ }), -/* 312 */ +/* 308 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const scan = __webpack_require__(313); -const parse = __webpack_require__(316); -const utils = __webpack_require__(314); -const constants = __webpack_require__(315); +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); /** @@ -41929,13 +41535,13 @@ module.exports = picomatch; /***/ }), -/* 313 */ +/* 309 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const utils = __webpack_require__(314); +const utils = __webpack_require__(310); const { CHAR_ASTERISK, /* * */ CHAR_AT, /* @ */ @@ -41952,7 +41558,7 @@ const { CHAR_RIGHT_CURLY_BRACE, /* } */ CHAR_RIGHT_PARENTHESES, /* ) */ CHAR_RIGHT_SQUARE_BRACKET /* ] */ -} = __webpack_require__(315); +} = __webpack_require__(311); const isPathSeparator = code => { return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; @@ -42319,7 +41925,7 @@ module.exports = scan; /***/ }), -/* 314 */ +/* 310 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -42332,7 +41938,7 @@ const { REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL -} = __webpack_require__(315); +} = __webpack_require__(311); exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); @@ -42390,7 +41996,7 @@ exports.wrapOutput = (input, state = {}, options = {}) => { /***/ }), -/* 315 */ +/* 311 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -42576,14 +42182,14 @@ module.exports = { /***/ }), -/* 316 */ +/* 312 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const constants = __webpack_require__(315); -const utils = __webpack_require__(314); +const constants = __webpack_require__(311); +const utils = __webpack_require__(310); /** * Constants @@ -43661,13 +43267,13 @@ module.exports = parse; /***/ }), -/* 317 */ +/* 313 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const merge2 = __webpack_require__(288); +const merge2 = __webpack_require__(284); function merge(streams) { const mergedStream = merge2(streams); streams.forEach((stream) => { @@ -43684,7 +43290,7 @@ function propagateCloseEventToSources(streams) { /***/ }), -/* 318 */ +/* 314 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -43701,14 +43307,14 @@ exports.isEmpty = isEmpty; /***/ }), -/* 319 */ +/* 315 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(320); -const provider_1 = __webpack_require__(347); +const stream_1 = __webpack_require__(316); +const provider_1 = __webpack_require__(343); class ProviderAsync extends provider_1.default { constructor() { super(...arguments); @@ -43736,16 +43342,16 @@ exports.default = ProviderAsync; /***/ }), -/* 320 */ +/* 316 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(137); -const fsStat = __webpack_require__(321); -const fsWalk = __webpack_require__(326); -const reader_1 = __webpack_require__(346); +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); @@ -43798,15 +43404,15 @@ exports.default = ReaderStream; /***/ }), -/* 321 */ +/* 317 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(322); -const sync = __webpack_require__(323); -const settings_1 = __webpack_require__(324); +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') { @@ -43829,7 +43435,7 @@ function getSettings(settingsOrOptions = {}) { /***/ }), -/* 322 */ +/* 318 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -43867,7 +43473,7 @@ function callSuccessCallback(callback, result) { /***/ }), -/* 323 */ +/* 319 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -43896,13 +43502,13 @@ exports.read = read; /***/ }), -/* 324 */ +/* 320 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(325); +const fs = __webpack_require__(321); class Settings { constructor(_options = {}) { this._options = _options; @@ -43919,13 +43525,13 @@ exports.default = Settings; /***/ }), -/* 325 */ +/* 321 */ /***/ (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, @@ -43942,16 +43548,16 @@ exports.createFileSystemAdapter = createFileSystemAdapter; /***/ }), -/* 326 */ +/* 322 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(327); -const stream_1 = __webpack_require__(342); -const sync_1 = __webpack_require__(343); -const settings_1 = __webpack_require__(345); +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') { @@ -43981,13 +43587,13 @@ function getSettings(settingsOrOptions = {}) { /***/ }), -/* 327 */ +/* 323 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(328); +const async_1 = __webpack_require__(324); class AsyncProvider { constructor(_root, _settings) { this._root = _root; @@ -44018,17 +43624,17 @@ function callSuccessCallback(callback, entries) { /***/ }), -/* 328 */ +/* 324 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const events_1 = __webpack_require__(155); -const fsScandir = __webpack_require__(329); -const fastq = __webpack_require__(338); -const common = __webpack_require__(340); -const reader_1 = __webpack_require__(341); +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); @@ -44118,15 +43724,15 @@ exports.default = AsyncReader; /***/ }), -/* 329 */ +/* 325 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(330); -const sync = __webpack_require__(335); -const settings_1 = __webpack_require__(336); +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') { @@ -44149,16 +43755,16 @@ function getSettings(settingsOrOptions = {}) { /***/ }), -/* 330 */ +/* 326 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(321); -const rpl = __webpack_require__(331); -const constants_1 = __webpack_require__(332); -const utils = __webpack_require__(333); +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); @@ -44246,7 +43852,7 @@ function callSuccessCallback(callback, result) { /***/ }), -/* 331 */ +/* 327 */ /***/ (function(module, exports) { module.exports = runParallel @@ -44300,7 +43906,7 @@ function runParallel (tasks, cb) { /***/ }), -/* 332 */ +/* 328 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44320,18 +43926,18 @@ exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_B /***/ }), -/* 333 */ +/* 329 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(334); +const fs = __webpack_require__(330); exports.fs = fs; /***/ }), -/* 334 */ +/* 330 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44356,15 +43962,15 @@ exports.createDirentFromStats = createDirentFromStats; /***/ }), -/* 335 */ +/* 331 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(321); -const constants_1 = __webpack_require__(332); -const utils = __webpack_require__(333); +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); @@ -44415,15 +44021,15 @@ exports.readdir = readdir; /***/ }), -/* 336 */ +/* 332 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const fsStat = __webpack_require__(321); -const fs = __webpack_require__(337); +const fsStat = __webpack_require__(317); +const fs = __webpack_require__(333); class Settings { constructor(_options = {}) { this._options = _options; @@ -44446,13 +44052,13 @@ exports.default = Settings; /***/ }), -/* 337 */ +/* 333 */ /***/ (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, @@ -44471,13 +44077,13 @@ exports.createFileSystemAdapter = createFileSystemAdapter; /***/ }), -/* 338 */ +/* 334 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var reusify = __webpack_require__(339) +var reusify = __webpack_require__(335) function fastqueue (context, worker, concurrency) { if (typeof context === 'function') { @@ -44651,7 +44257,7 @@ module.exports = fastqueue /***/ }), -/* 339 */ +/* 335 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44691,7 +44297,7 @@ module.exports = reusify /***/ }), -/* 340 */ +/* 336 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44722,13 +44328,13 @@ exports.joinPathSegments = joinPathSegments; /***/ }), -/* 341 */ +/* 337 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const common = __webpack_require__(340); +const common = __webpack_require__(336); class Reader { constructor(_root, _settings) { this._root = _root; @@ -44740,14 +44346,14 @@ exports.default = Reader; /***/ }), -/* 342 */ +/* 338 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(137); -const async_1 = __webpack_require__(328); +const stream_1 = __webpack_require__(138); +const async_1 = __webpack_require__(324); class StreamProvider { constructor(_root, _settings) { this._root = _root; @@ -44777,13 +44383,13 @@ exports.default = StreamProvider; /***/ }), -/* 343 */ +/* 339 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(344); +const sync_1 = __webpack_require__(340); class SyncProvider { constructor(_root, _settings) { this._root = _root; @@ -44798,15 +44404,15 @@ exports.default = SyncProvider; /***/ }), -/* 344 */ +/* 340 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsScandir = __webpack_require__(329); -const common = __webpack_require__(340); -const reader_1 = __webpack_require__(341); +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); @@ -44864,14 +44470,14 @@ exports.default = SyncReader; /***/ }), -/* 345 */ +/* 341 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const fsScandir = __webpack_require__(329); +const fsScandir = __webpack_require__(325); class Settings { constructor(_options = {}) { this._options = _options; @@ -44897,15 +44503,15 @@ exports.default = Settings; /***/ }), -/* 346 */ +/* 342 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const fsStat = __webpack_require__(321); -const utils = __webpack_require__(291); +const fsStat = __webpack_require__(317); +const utils = __webpack_require__(287); class Reader { constructor(_settings) { this._settings = _settings; @@ -44937,17 +44543,17 @@ exports.default = Reader; /***/ }), -/* 347 */ +/* 343 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const deep_1 = __webpack_require__(348); -const entry_1 = __webpack_require__(351); -const error_1 = __webpack_require__(352); -const entry_2 = __webpack_require__(353); +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; @@ -44992,14 +44598,14 @@ exports.default = Provider; /***/ }), -/* 348 */ +/* 344 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(291); -const partial_1 = __webpack_require__(349); +const utils = __webpack_require__(287); +const partial_1 = __webpack_require__(345); class DeepFilter { constructor(_settings, _micromatchOptions) { this._settings = _settings; @@ -45053,13 +44659,13 @@ exports.default = DeepFilter; /***/ }), -/* 349 */ +/* 345 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const matcher_1 = __webpack_require__(350); +const matcher_1 = __webpack_require__(346); class PartialMatcher extends matcher_1.default { match(filepath) { const parts = filepath.split('/'); @@ -45098,13 +44704,13 @@ exports.default = PartialMatcher; /***/ }), -/* 350 */ +/* 346 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(291); +const utils = __webpack_require__(287); class Matcher { constructor(_patterns, _settings, _micromatchOptions) { this._patterns = _patterns; @@ -45155,13 +44761,13 @@ exports.default = Matcher; /***/ }), -/* 351 */ +/* 347 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(291); +const utils = __webpack_require__(287); class EntryFilter { constructor(_settings, _micromatchOptions) { this._settings = _settings; @@ -45217,13 +44823,13 @@ exports.default = EntryFilter; /***/ }), -/* 352 */ +/* 348 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(291); +const utils = __webpack_require__(287); class ErrorFilter { constructor(_settings) { this._settings = _settings; @@ -45239,13 +44845,13 @@ exports.default = ErrorFilter; /***/ }), -/* 353 */ +/* 349 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(291); +const utils = __webpack_require__(287); class EntryTransformer { constructor(_settings) { this._settings = _settings; @@ -45272,15 +44878,15 @@ exports.default = EntryTransformer; /***/ }), -/* 354 */ +/* 350 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(137); -const stream_2 = __webpack_require__(320); -const provider_1 = __webpack_require__(347); +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); @@ -45310,14 +44916,14 @@ exports.default = ProviderStream; /***/ }), -/* 355 */ +/* 351 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(356); -const provider_1 = __webpack_require__(347); +const sync_1 = __webpack_require__(352); +const provider_1 = __webpack_require__(343); class ProviderSync extends provider_1.default { constructor() { super(...arguments); @@ -45340,15 +44946,15 @@ exports.default = ProviderSync; /***/ }), -/* 356 */ +/* 352 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(321); -const fsWalk = __webpack_require__(326); -const reader_1 = __webpack_require__(346); +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); @@ -45390,14 +44996,14 @@ exports.default = ReaderSync; /***/ }), -/* 357 */ +/* 353 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(133); -const os = __webpack_require__(120); +const fs = __webpack_require__(134); +const os = __webpack_require__(121); const CPU_COUNT = os.cpus().length; exports.DEFAULT_FILE_SYSTEM_ADAPTER = { lstat: fs.lstat, @@ -45449,13 +45055,13 @@ exports.default = Settings; /***/ }), -/* 358 */ +/* 354 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(359); +const pathType = __webpack_require__(355); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -45531,13 +45137,13 @@ module.exports.sync = (input, options) => { /***/ }), -/* 359 */ +/* 355 */ /***/ (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); async function isType(fsStatType, statsMethodName, filePath) { if (typeof filePath !== 'string') { @@ -45581,17 +45187,17 @@ exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 360 */ +/* 356 */ /***/ (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 fastGlob = __webpack_require__(289); -const gitIgnore = __webpack_require__(361); -const slash = __webpack_require__(362); +const fastGlob = __webpack_require__(285); +const gitIgnore = __webpack_require__(357); +const slash = __webpack_require__(358); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -45705,7 +45311,7 @@ module.exports.sync = options => { /***/ }), -/* 361 */ +/* 357 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -46308,7 +45914,7 @@ if ( /***/ }), -/* 362 */ +/* 358 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46326,12 +45932,12 @@ module.exports = path => { /***/ }), -/* 363 */ +/* 359 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {Transform} = __webpack_require__(137); +const {Transform} = __webpack_require__(138); class ObjectTransform extends Transform { constructor() { @@ -46379,61 +45985,7 @@ module.exports = { /***/ }), -/* 364 */ -/***/ (function(module, exports, __webpack_require__) { - -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -var isExtglob = __webpack_require__(299); -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; -}; - - -/***/ }), -/* 365 */ +/* 360 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46455,7 +46007,7 @@ module.exports = path_ => { /***/ }), -/* 366 */ +/* 361 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46483,15 +46035,15 @@ module.exports = (childPath, parentPath) => { /***/ }), -/* 367 */ +/* 362 */ /***/ (function(module, exports, __webpack_require__) { -const assert = __webpack_require__(139) +const assert = __webpack_require__(140) const path = __webpack_require__(4) -const fs = __webpack_require__(133) +const fs = __webpack_require__(134) let glob = undefined try { - glob = __webpack_require__(146) + glob = __webpack_require__(147) } catch (_err) { // treat glob as optional. } @@ -46849,12 +46401,12 @@ rimraf.sync = rimrafSync /***/ }), -/* 368 */ +/* 363 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const AggregateError = __webpack_require__(369); +const AggregateError = __webpack_require__(364); module.exports = async ( iterable, @@ -46937,13 +46489,13 @@ module.exports = async ( /***/ }), -/* 369 */ +/* 364 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const indentString = __webpack_require__(370); -const cleanStack = __webpack_require__(371); +const indentString = __webpack_require__(365); +const cleanStack = __webpack_require__(366); const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); @@ -46991,7 +46543,7 @@ module.exports = AggregateError; /***/ }), -/* 370 */ +/* 365 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47033,12 +46585,12 @@ module.exports = (string, count = 1, options) => { /***/ }), -/* 371 */ +/* 366 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const os = __webpack_require__(120); +const os = __webpack_require__(121); const extractPathRegex = /\s+at.*(?:\(|\s)(.*)\)?/; const pathRegex = /^(?:(?:(?:node|(?:internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)\.js:\d+:\d+)|native)/; @@ -47080,47 +46632,221 @@ module.exports = (stack, options) => { /***/ }), -/* 372 */ +/* 367 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const chalk = __webpack_require__(373); -const cliCursor = __webpack_require__(378); -const cliSpinners = __webpack_require__(382); -const logSymbols = __webpack_require__(384); +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); + +const TEXT = Symbol('text'); +const PREFIX_TEXT = Symbol('prefixText'); + +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; + } + + if (event === 'data' && data.includes(ASCII_ETX_CODE)) { + process.emit('SIGINT'); + } + + Reflect.apply(self.oldEmit, this, [event, data, ...args]); + } else { + Reflect.apply(process.stdin.emit, this, [event, data, ...args]); + } + }; + } + + start() { + this.requests++; + + if (this.requests === 1) { + this.realStart(); + } + } + + stop() { + if (this.requests <= 0) { + throw new Error('`stop` called more times than `start`'); + } + + this.requests--; + + if (this.requests === 0) { + this.realStop(); + } + } + + 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 + }); + + this.rl.on('SIGINT', () => { + if (process.listenerCount('SIGINT') === 0) { + process.emit('SIGINT'); + } else { + this.rl.close(); + process.kill(process.pid, 'SIGINT'); + } + }); + } + + realStop() { + if (process.platform === 'win32') { + return; + } + + this.rl.close(); + this.rl = undefined; + } +} + +let stdinDiscarder; class Ora { constructor(options) { + if (!stdinDiscarder) { + stdinDiscarder = new StdinDiscarder(); + } + if (typeof options === 'string') { options = { text: options }; } - this.options = Object.assign({ + this.options = { text: '', color: 'cyan', - stream: process.stderr - }, options); + stream: process.stderr, + discardStdin: true, + ...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 + this.spinner = this.options.spinner; - if (this.spinner.frames === undefined) { - throw new Error('Spinner must define `frames`'); - } - - this.text = this.options.text; 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 = null; + this.id = undefined; + this.isEnabled = typeof this.options.isEnabled === 'boolean' ? this.options.isEnabled : isInteractive({stream: this.stream}); + + // 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; + } + + 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'); + } + + this._indent = indent; + } + + _updateInterval(interval) { + if (interval !== undefined) { + this.interval = interval; + } + } + + get spinner() { + return this._spinner; + } + + set spinner(spinner) { this.frameIndex = 0; - this.enabled = typeof this.options.enabled === 'boolean' ? this.options.enabled : ((this.stream && this.stream.isTTY) && !process.env.CI); + + if (typeof spinner === 'object') { + if (spinner.frames === undefined) { + throw new Error('The given spinner must have a `frames` property'); + } + + 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); + } + + get text() { + return this[TEXT]; + } + + get prefixText() { + return this[PREFIX_TEXT]; + } + + get isSpinning() { + return this.id !== undefined; + } + + 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); + } + + set text(value) { + this[TEXT] = value; + this.updateLineCount(); } + + set prefixText(value) { + this[PREFIX_TEXT] = value; + this.updateLineCount(); + } + frame() { - const frames = this.spinner.frames; + const {frames} = this.spinner; let frame = frames[this.frameIndex]; if (this.color) { @@ -47128,92 +46854,129 @@ class Ora { } 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 frame + ' ' + this.text; + return fullPrefixText + frame + fullText; } + clear() { - if (!this.enabled) { + if (!this.isEnabled || !this.stream.isTTY) { return this; } - this.stream.clearLine(); - this.stream.cursorTo(0); + for (let i = 0; i < this.linesToClear; i++) { + if (i > 0) { + this.stream.moveCursor(0, -1); + } + + this.stream.clearLine(); + this.stream.cursorTo(this.indent); + } + + this.linesToClear = 0; return this; } + render() { this.clear(); this.stream.write(this.frame()); + this.linesToClear = this.lineCount; return this; } + start(text) { if (text) { this.text = text; } - if (!this.enabled || this.id) { + if (!this.isEnabled) { + if (this.text) { + this.stream.write(`- ${this.text}\n`); + } + + return this; + } + + if (this.isSpinning) { return this; } - cliCursor.hide(this.stream); + 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; } + stop() { - if (!this.enabled) { + if (!this.isEnabled) { return this; } clearInterval(this.id); - this.id = null; + this.id = undefined; this.frameIndex = 0; this.clear(); - cliCursor.show(this.stream); + if (this.hideCursor) { + cliCursor.show(this.stream); + } + + if (this.discardStdin && process.stdin.isTTY && this.isDiscardingStdin) { + stdinDiscarder.stop(); + this.isDiscardingStdin = false; + } return this; } + succeed(text) { return this.stopAndPersist({symbol: logSymbols.success, text}); } + fail(text) { return this.stopAndPersist({symbol: logSymbols.error, text}); } + warn(text) { return this.stopAndPersist({symbol: logSymbols.warning, text}); } + info(text) { return this.stopAndPersist({symbol: logSymbols.info, text}); } - stopAndPersist(options) { - if (!this.enabled) { - return this; - } - // Legacy argument - // TODO: Deprecate sometime in the future - if (typeof options === 'string') { - options = { - symbol: options - }; - } - - options = options || {}; + 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(`${options.symbol || ' '} ${options.text || this.text}\n`); + this.stream.write(`${fullPrefixText}${options.symbol || ' '}${fullText}\n`); return this; } } -module.exports = function (opts) { - return new Ora(opts); +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'); } @@ -47221,277 +46984,330 @@ module.exports.promise = (action, options) => { const spinner = new Ora(options); spinner.start(); - action.then( - () => { + (async () => { + try { + await action; spinner.succeed(); - }, - () => { + } catch (_) { spinner.fail(); } - ); + })(); return spinner; }; /***/ }), -/* 373 */ -/***/ (function(module, exports, __webpack_require__) { +/* 368 */ +/***/ (function(module, exports) { -"use strict"; +module.exports = require("readline"); -const escapeStringRegexp = __webpack_require__(178); -const ansiStyles = __webpack_require__(374); -const stdoutColor = __webpack_require__(375).stdout; +/***/ }), +/* 369 */ +/***/ (function(module, exports, __webpack_require__) { -const template = __webpack_require__(377); +"use strict"; -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); +const ansiStyles = __webpack_require__(370); +const {stdout: stdoutColor, stderr: stderrColor} = __webpack_require__(120); +const { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex +} = __webpack_require__(374); // `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; - -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); +const levelMapping = [ + 'ansi', + 'ansi', + 'ansi256', + 'ansi16m' +]; const styles = Object.create(null); -function applyOptions(obj, options) { - options = options || {}; +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'); + } // 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; + const colorLevel = stdoutColor ? stdoutColor.level : 0; + object.level = options.level === undefined ? colorLevel : options.level; +}; + +class ChalkClass { + constructor(options) { + return chalkFactory(options); + } } -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); +const chalkFactory = options => { + const chalk = {}; + applyOptions(chalk, options); - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; + chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); - chalk.template.constructor = Chalk; + chalk.template.constructor = () => { + throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); + }; - return chalk.template; - } + chalk.template.Instance = ChalkClass; - applyOptions(this, options); -} + return chalk.template; +}; -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; +function Chalk(options) { + return chalkFactory(options); } -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - - styles[key] = { +for (const [styleName, style] of Object.entries(ansiStyles)) { + styles[styleName] = { get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); + Object.defineProperty(this, styleName, {value: builder}); + return builder; } }; } styles.visible = { get() { - return build.call(this, this._styles || [], true, 'visible'); + const builder = createBuilder(this, this._styler, true); + Object.defineProperty(this, 'visible', {value: builder}); + return builder; } }; -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } +const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; +for (const model of usedModels) { 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); + 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); }; } }; } -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } - +for (const model of usedModels) { 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); + 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 proto = Object.defineProperties(() => {}, styles); - -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; - - builder._styles = _styles; - builder._empty = _empty; - - const self = this; - - Object.defineProperty(builder, 'level', { +const proto = Object.defineProperties(() => {}, { + ...styles, + level: { enumerable: true, get() { - return self.level; + return this._generator.level; }, set(level) { - self.level = level; + this._generator.level = level; } - }); + } +}); - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); +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; + } - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; + return { + open, + close, + openAll, + closeAll, + parent + }; +}; + +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 - return builder; -} + builder._generator = self; + builder._styler = _styler; + builder._isEmpty = _isEmpty; -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]); + return builder; +}; - if (argsLen === 0) { - return ''; +const applyStyle = (self, string) => { + if (self.level <= 0 || !string) { + return self._isEmpty ? '' : string; } - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } + let styler = self._styler; - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; + if (styler === undefined) { + return string; } - // 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 {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); - 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; + styler = styler.parent; + } + } - // 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}`); + // 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); } - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; + return openAll + string + closeAll; +}; - return str; -} +let template; +const chalkTag = (chalk, ...strings) => { + const [firstString] = strings; -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { + if (!Array.isArray(firstString)) { // If chalk() was called by itself or with a string, // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); + return strings.join(' '); } - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; + const arguments_ = strings.slice(1); + const parts = [firstString.raw[0]]; - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); + 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); -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript +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; + +// For TypeScript +chalk.Level = { + None: 0, + Basic: 1, + Ansi256: 2, + TrueColor: 3, + 0: 'None', + 1: 'Basic', + 2: 'Ansi256', + 3: 'TrueColor' +}; + +module.exports = chalk; /***/ }), -/* 374 */ +/* 370 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(180); -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); +const wrapAnsi16 = (fn, offset) => (...args) => { + const code = fn(...args); return `\u001B[${code + offset}m`; }; -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); +const wrapAnsi256 = (fn, offset) => (...args) => { + const code = fn(...args); return `\u001B[${38 + offset};5;${code}m`; }; -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); +const wrapAnsi16m = (fn, offset) => (...args) => { + const rgb = fn(...args); return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; }; +const ansi2ansi = n => n; +const rgb2rgb = (r, g, b) => [r, g, b]; + +const setLazyProperty = (object, property, get) => { + Object.defineProperty(object, property, { + get: () => { + const value = get(); + + Object.defineProperty(object, property, { + value, + enumerable: true, + configurable: true + }); + + return value; + }, + enumerable: true, + configurable: true + }); +}; + +/** @type {typeof import('color-convert')} */ +let colorConvert; +const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { + if (colorConvert === undefined) { + colorConvert = __webpack_require__(371); + } + + const offset = isBackground ? 10 : 0; + const styles = {}; + + 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); + } + } + + return styles; +}; + function assembleStyles() { const codes = new Map(); const styles = { @@ -47515,9 +47331,9 @@ function assembleStyles() { magenta: [35, 39], cyan: [36, 39], white: [37, 39], - gray: [90, 39], // Bright color + blackBright: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], @@ -47548,15 +47364,14 @@ function assembleStyles() { } }; - // 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]; + // 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; + 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` @@ -47571,65 +47386,22 @@ function assembleStyles() { value: group, enumerable: false }); - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); } - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; + Object.defineProperty(styles, 'codes', { + value: codes, + enumerable: false + }); 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); - } - } + 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)); return styles; } @@ -47640,10563 +47412,14559 @@ Object.defineProperty(module, 'exports', { get: assembleStyles }); -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) +/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(115)(module))) /***/ }), -/* 375 */ +/* 371 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +const conversions = __webpack_require__(372); +const route = __webpack_require__(373); -const os = __webpack_require__(120); -const hasFlag = __webpack_require__(376); +const convert = {}; -const env = process.env; +const models = Object.keys(conversions); -let forceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false')) { - forceColor = false; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env) { - forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; -} +function wrapRaw(fn) { + const wrappedFn = function (...args) { + const arg0 = args[0]; + if (arg0 === undefined || arg0 === null) { + return arg0; + } -function translateLevel(level) { - if (level === 0) { - return false; - } + if (arg0.length > 1) { + args = arg0; + } - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 + return fn(args); }; -} - -function supportsColor(stream) { - if (forceColor === false) { - return 0; - } - - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } - if (hasFlag('color=256')) { - return 2; + // Preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; } - if (stream && !stream.isTTY && forceColor !== true) { - return 0; - } + return wrappedFn; +} - const min = forceColor ? 1 : 0; +function wrapRounded(fn) { + const wrappedFn = function (...args) { + const arg0 = args[0]; - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. 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(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; + if (arg0 === undefined || arg0 === null) { + return arg0; } - return 1; - } - - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; + if (arg0.length > 1) { + args = arg0; } - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env) { - const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + const result = fn(args); - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default + // 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]); + } } - } - - 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 result; + }; - if (env.TERM === 'dumb') { - return min; + // Preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; } - return min; + return wrappedFn; } -function getSupportLevel(stream) { - const level = supportsColor(stream); - return translateLevel(level); -} +models.forEach(fromModel => { + convert[fromModel] = {}; -module.exports = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); + const routes = route(fromModel); + const routeModels = Object.keys(routes); -/***/ }), -/* 376 */ -/***/ (function(module, exports, __webpack_require__) { + routeModels.forEach(toModel => { + const fn = routes[toModel]; -"use strict"; + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); -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); -}; +module.exports = convert; /***/ }), -/* 377 */ +/* 372 */ /***/ (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'] -]); +/* MIT license */ +/* eslint-disable no-mixed-operators */ +const cssKeywords = __webpack_require__(118); -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } +// 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.) - return ESCAPES.get(c) || c; +const reverseKeywords = {}; +for (const key of Object.keys(cssKeywords)) { + reverseKeywords[cssKeywords[key]] = key; } -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; -} +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']} +}; -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; +module.exports = convert; - const results = []; - let matches; +// Hide .channels and .labels properties +for (const model of Object.keys(convert)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); } - return results; + 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}); } -function buildStyle(chalk, styles) { - const enabled = {}; +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; - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } + 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; } - 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}`); - } + h = Math.min(h * 60, 360); - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } + if (h < 0) { + h += 360; } - 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('')); + const l = (min + max) / 2; - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); } - return chunks.join(''); + return [h, s * 100, l * 100]; }; +convert.rgb.hsv = function (rgb) { + let rdif; + let gdif; + let bdif; + let h; + let s; -/***/ }), -/* 378 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const restoreCursor = __webpack_require__(379); + 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; + }; -let hidden = false; + if (diff === 0) { + h = 0; + s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); -exports.show = stream => { - const s = stream || process.stderr; + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } - if (!s.isTTY) { - return; + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } } - hidden = false; - s.write('\u001b[?25h'); + return [ + h * 360, + s * 100, + v * 100 + ]; }; -exports.hide = stream => { - const s = stream || process.stderr; +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)); - if (!s.isTTY) { - return; - } + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - restoreCursor(); - hidden = true; - s.write('\u001b[?25l'); + return [h, w * 100, b * 100]; }; -exports.toggle = (force, stream) => { - if (force !== undefined) { - hidden = force; - } +convert.rgb.cmyk = function (rgb) { + const r = rgb[0] / 255; + const g = rgb[1] / 255; + const b = rgb[2] / 255; - if (hidden) { - exports.show(stream); - } else { - exports.hide(stream); - } + 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; + + 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) + ); +} -/***/ }), -/* 379 */ -/***/ (function(module, exports, __webpack_require__) { +convert.rgb.keyword = function (rgb) { + const reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } -"use strict"; + let currentClosestDistance = Infinity; + let currentClosestKeyword; -const onetime = __webpack_require__(380); -const signalExit = __webpack_require__(217); + for (const keyword of Object.keys(cssKeywords)) { + const value = cssKeywords[keyword]; -module.exports = onetime(() => { - signalExit(() => { - process.stderr.write('\u001b[?25h'); - }, {alwaysLast: true}); -}); + // Compute comparative distance + const distance = comparativeDistance(rgb, value); + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } -/***/ }), -/* 380 */ -/***/ (function(module, exports, __webpack_require__) { + return currentClosestKeyword; +}; -"use strict"; +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; + + // 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); + + 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); + + return [x * 100, y * 100, z * 100]; +}; + +convert.rgb.lab = function (rgb) { + const xyz = convert.rgb.xyz(rgb); + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; + + 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); + + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); + + return [l, a, b]; +}; -const mimicFn = __webpack_require__(381); +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; -module.exports = (fn, opts) => { - // TODO: Remove this in v3 - if (opts === true) { - throw new TypeError('The second argument is now an options object'); + if (s === 0) { + val = l * 255; + return [val, val, val]; } - if (typeof fn !== 'function') { - throw new TypeError('Expected a function'); + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; } - opts = opts || {}; + const t1 = 2 * l - t2; - let ret; - let called = false; - const fnName = fn.displayName || fn.name || ''; + const rgb = [0, 0, 0]; + for (let i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } - const onetime = function () { - if (called) { - if (opts.throw === true) { - throw new Error(`Function \`${fnName}\` can only be called once`); - } + if (t3 > 1) { + t3--; + } - return ret; + 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; } - called = true; - ret = fn.apply(this, arguments); - fn = null; + rgb[i] = val * 255; + } - return ret; - }; + return rgb; +}; - mimicFn(onetime, fn); +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); - return onetime; -}; + 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); + return [h, sv * 100, v * 100]; +}; -/***/ }), -/* 381 */ -/***/ (function(module, exports, __webpack_require__) { +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; -"use strict"; + 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; -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)); + 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]; } - - return to; }; +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; -/***/ }), -/* 382 */ -/***/ (function(module, exports, __webpack_require__) { + l = (2 - s) * v; + const lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; -"use strict"; + return [h, sl * 100, l * 100]; +}; -module.exports = __webpack_require__(383); +// 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; + // Wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } -/***/ }), -/* 383 */ -/***/ (function(module) { + const i = Math.floor(6 * h); + const v = 1 - bl; + f = 6 * h - i; -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 ((i & 0x01) !== 0) { + f = 1 - f; + } -/***/ }), -/* 384 */ -/***/ (function(module, exports, __webpack_require__) { + const n = wh + f * (v - wh); // Linear interpolation -"use strict"; + 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 */ -const chalk = __webpack_require__(385); + return [r * 255, g * 255, b * 255]; +}; -const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; +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; -const main = { - info: chalk.blue('ℹ'), - success: chalk.green('✔'), - warning: chalk.yellow('⚠'), - error: chalk.red('✖') -}; + 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); -const fallbacks = { - info: chalk.blue('i'), - success: chalk.green('√'), - warning: chalk.yellow('‼'), - error: chalk.red('×') + return [r * 255, g * 255, b * 255]; }; -module.exports = isSupported ? main : fallbacks; +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; + 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); -/***/ }), -/* 385 */ -/***/ (function(module, exports, __webpack_require__) { + // Assume sRGB + r = r > 0.0031308 + ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) + : r * 12.92; -"use strict"; + g = g > 0.0031308 + ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) + : g * 12.92; -const escapeStringRegexp = __webpack_require__(178); -const ansiStyles = __webpack_require__(386); -const stdoutColor = __webpack_require__(184).stdout; + b = b > 0.0031308 + ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) + : b * 12.92; -const template = __webpack_require__(387); + 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 isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); + return [r * 255, g * 255, b * 255]; +}; -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; +convert.xyz.lab = function (xyz) { + let x = xyz[0]; + let y = xyz[1]; + let z = xyz[2]; -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); + x /= 95.047; + y /= 100; + z /= 108.883; -const styles = Object.create(null); + 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 applyOptions(obj, options) { - options = options || {}; + const l = (116 * y) - 16; + const a = 500 * (x - y); + const b = 200 * (y - z); - // 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; -} + return [l, a, b]; +}; -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); +convert.lab.xyz = function (lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let x; + let y; + let z; - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); + 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; - chalk.template.constructor = Chalk; + x *= 95.047; + y *= 100; + z *= 108.883; - return chalk.template; + return [x, y, z]; +}; + +convert.lab.lch = function (lab) { + const l = lab[0]; + const a = lab[1]; + const b = lab[2]; + let h; + + const hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; + + if (h < 0) { + h += 360; } - applyOptions(this, options); -} + const c = Math.sqrt(a * a + b * b); -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; -} + return [l, c, h]; +}; -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); +convert.lch.lab = function (lch) { + const l = lch[0]; + const c = lch[1]; + const h = lch[2]; - styles[key] = { - get() { - const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; -} + const hr = h / 360 * 2 * Math.PI; + const a = c * Math.cos(hr); + const b = c * Math.sin(hr); -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } + return [l, a, b]; }; -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } +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 - 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); - }; - } - }; -} + value = Math.round(value / 50); -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; + if (value === 0) { + return 30; } - 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); - }; - } - }; -} + let ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); -const proto = Object.defineProperties(() => {}, styles); + if (value === 2) { + ansi += 60; + } -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; + return ansi; +}; - builder._styles = _styles; - builder._empty = _empty; +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]); +}; - const self = this; +convert.rgb.ansi256 = function (args) { + const r = args[0]; + const g = args[1]; + const b = args[2]; - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; + // 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; } - }); - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; + if (r > 248) { + return 231; } - }); - - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; - // `__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 Math.round(((r - 8) / 247) * 24) + 232; + } - return builder; -} + const ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); -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]); + return ansi; +}; - if (argsLen === 0) { - return ''; - } +convert.ansi16.rgb = function (args) { + let color = args % 10; - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; + // Handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; } - } - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } + color = color / 10.5 * 255; - // 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 = ''; + return [color, color, color]; } - 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; + 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; - // 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}`); + return [r, g, b]; +}; + +convert.ansi256.rgb = function (args) { + // Handle greyscale + if (args >= 232) { + const c = (args - 232) * 10 + 8; + return [c, c, c]; } - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles.dim.open = originalDim; + args -= 16; - return str; -} + 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 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(' '); + return [r, g, b]; +}; + +convert.rgb.hex = function (args) { + const integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); + + const string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; + +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]; } - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; + let colorString = match[0]; - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); + if (match[0].length === 3) { + colorString = colorString.split('').map(char => { + return char + char; + }).join(''); } - return template(chalk, parts.join('')); -} + const integer = parseInt(colorString, 16); + const r = (integer >> 16) & 0xFF; + const g = (integer >> 8) & 0xFF; + const b = integer & 0xFF; -Object.defineProperties(Chalk.prototype, styles); + return [r, g, b]; +}; -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript +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; + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; + } -/***/ }), -/* 386 */ -/***/ (function(module, exports, __webpack_require__) { + 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; + } -"use strict"; -/* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(180); + hue /= 6; + hue %= 1; -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${code + offset}m`; + return [hue * 360, chroma * 100, grayscale * 100]; }; -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};5;${code}m`; +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)); + + let f = 0; + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } + + return [hsl[0], c * 100, f * 100]; }; -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; +convert.hsv.hcg = function (hsv) { + const s = hsv[1] / 100; + const v = hsv[2] / 100; + + const c = s * v; + let f = 0; + + if (c < 1.0) { + f = (v - c) / (1 - c); + } + + return [hsv[0], c * 100, f * 100]; }; -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], +convert.hcg.rgb = function (hcg) { + const h = hcg[0] / 360; + const c = hcg[1] / 100; + const g = hcg[2] / 100; - // 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], + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } - // 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] - } - }; + const pure = [0, 0, 0]; + const hi = (h % 1) * 6; + const v = hi % 1; + const w = 1 - v; + let mg = 0; - // Fix humans - styles.color.grey = styles.color.gray; + /* 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 */ - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; + mg = (1.0 - c) * g; - for (const styleName of Object.keys(group)) { - const style = group[styleName]; + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; +convert.hcg.hsv = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; - group[styleName] = styles[styleName]; + const v = c + g * (1.0 - c); + let f = 0; - codes.set(style[0], style[1]); - } + if (v > 0.0) { + f = c / v; + } - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); + return [hcg[0], f * 100, v * 100]; +}; - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); +convert.hcg.hsl = function (hcg) { + const c = hcg[1] / 100; + const g = hcg[2] / 100; + + const l = g * (1.0 - c) + 0.5 * c; + let s = 0; + + 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 ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; + return [hcg[0], s * 100, l * 100]; +}; - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; +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]; +}; - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; +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; - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; + if (c < 1) { + g = (v - c) / (1 - c); + } - for (let key of Object.keys(colorConvert)) { - if (typeof colorConvert[key] !== 'object') { - continue; - } + return [hwb[0], c * 100, g * 100]; +}; - const suite = colorConvert[key]; +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; +}; - if (key === 'ansi16') { - key = 'ansi'; - } +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } +convert.gray.hsl = function (args) { + return [0, 0, args[0]]; +}; - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } - } +convert.gray.hsv = convert.gray.hsl; - return styles; -} +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; +}; -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; + +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; +}; + +convert.gray.hex = function (gray) { + const val = Math.round(gray[0] / 100 * 255) & 0xFF; + const integer = (val << 16) + (val << 8) + val; + + 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]; +}; -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 387 */ +/* 373 */ /***/ (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 conversions = __webpack_require__(372); -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); +/* + This function routes a model to all other models. -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } + 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). - return ESCAPES.get(c) || c; -} + conversions that are not possible simply are not included. +*/ -function parseArguments(name, args) { - const results = []; - const chunks = args.trim().split(/\s*,\s*/g); - let matches; +function buildGraph() { + const graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + const models = Object.keys(conversions); - 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}')`); - } + 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 results; + return graph; } -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + const graph = buildGraph(); + const queue = [fromModel]; // Unshift -> queue -> pop - const results = []; - let matches; + graph[fromModel].distance = 0; - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; + while (queue.length) { + const current = queue.pop(); + const adjacents = Object.keys(conversions[current]); - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); + 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 results; + return graph; } -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); - } - } +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} - 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}`); - } +function wrapConversion(toModel, graph) { + const path = [graph[toModel].parent, toModel]; + let fn = conversions[graph[toModel].parent][toModel]; - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } + 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; } - return current; + fn.conversion = path; + return fn; } -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'); - } +module.exports = function (fromModel) { + const graph = deriveBFS(fromModel); + const conversion = {}; - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); + const models = Object.keys(graph); + for (let len = models.length, i = 0; i < len; i++) { + const toModel = models[i]; + const node = graph[toModel]; - chunks.push(chunk.join('')); + if (node.parent === null) { + // No possible conversion, or this node is the source model. + continue; + } - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); + conversion[toModel] = wrapConversion(toModel, graph); } - return chunks.join(''); + return conversion; }; + /***/ }), -/* 388 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 374 */ +/***/ (function(module, 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 stringReplaceAll = (string, substring, replacer) => { + let index = string.indexOf(substring); + if (index === -1) { + return string; + } -const RunCommand = { - description: 'Run script defined in package.json in each package that contains that script.', - name: 'run', + 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); - async run(projects, projectGraph, { - extraArgs - }) { - const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projects, projectGraph); + returnValue += string.substr(endIndex); + return returnValue; +}; - if (extraArgs.length === 0) { - throw new _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"]('No script specified'); - } +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); - 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`); - } - }); - } + returnValue += string.substr(endIndex); + return returnValue; +}; +module.exports = { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex }; + /***/ }), -/* 389 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 375 */ +/***/ (function(module, 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__(390); -/* - * 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 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'] +]); +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)); + } -/** - * 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. - */ + if (u && bracket) { + return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); + } -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. - */ + return ESCAPES.get(c) || c; +} -const WatchCommand = { - description: 'Runs `kbn:watch` script for every project.', - name: 'watch', +function parseArguments(name, arguments_) { + const results = []; + const chunks = arguments_.trim().split(/\s*,\s*/g); + let matches; - async run(projects, projectGraph) { - const projectsToWatch = new Map(); + 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}')`); + } + } - 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); - } - } + return results; +} - 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'.`); - } +function parseStyle(style) { + STYLE_REGEX.lastIndex = 0; - 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 results = []; + let matches; - const shouldWatchKibanaProject = projectsToWatch.delete(kibanaProjectName); - const batchedProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_3__["topologicallyBatchProjects"])(projectsToWatch, projectGraph); + while ((matches = STYLE_REGEX.exec(style)) !== null) { + const name = matches[1]; - if (shouldWatchKibanaProject) { - batchedProjects.push([projects.get(kibanaProjectName)]); - } + if (matches[2]) { + const args = parseArguments(name, matches[2]); + results.push([name].concat(args)); + } else { + results.push([name]); + } + } - 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}).`); - }); - } + return results; +} -}; +function buildStyle(chalk, styles) { + const enabled = {}; -/***/ }), -/* 390 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + for (const layer of styles) { + for (const style of layer.styles) { + enabled[style[0]] = layer.inverse ? null : style.slice(1); + } + } -"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__(391); -/* - * 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. - */ + let current = chalk; + for (const [styleName, styles] of Object.entries(enabled)) { + if (!Array.isArray(styles)) { + continue; + } + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); + } -/** - * Number of milliseconds we wait before we fall back to the default watch handler. - */ + current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; + } -const defaultHandlerDelay = 3000; -/** - * If default watch handler is used, then it's the number of milliseconds we wait for - * any build output before we consider watch task ready. - */ + return current; +} -const defaultHandlerReadinessTimeout = 2000; -/** - * Describes configurable watch options. - */ +module.exports = (chalk, temporary) => { + const styles = []; + const chunks = []; + let chunk = []; -function getWatchHandlers(buildOutput$, { - handlerDelay = defaultHandlerDelay, - handlerReadinessTimeout = defaultHandlerReadinessTimeout -}) { - const typescriptHandler = buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('$ tsc')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["map"])(() => buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('Compilation complete.')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["mapTo"])('tsc')))); - const webpackHandler = buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('$ webpack')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["map"])(() => buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('Chunk Names')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["mapTo"])('webpack')))); - const defaultHandler = rxjs__WEBPACK_IMPORTED_MODULE_0__["of"](undefined).pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["delay"])(handlerReadinessTimeout), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["map"])(() => buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["timeout"])(handlerDelay), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["catchError"])(() => rxjs__WEBPACK_IMPORTED_MODULE_0__["of"]('timeout'))))); - return [typescriptHandler, webpackHandler, defaultHandler]; -} + // 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'); + } -function waitUntilWatchIsReady(stream, opts = {}) { - const buildOutput$ = new rxjs__WEBPACK_IMPORTED_MODULE_0__["Subject"](); + chunks.push(buildStyle(chalk, styles)(chunk.join(''))); + chunk = []; + styles.pop(); + } else { + chunk.push(character); + } + }); - const onDataListener = data => buildOutput$.next(data.toString('utf-8')); + chunks.push(chunk.join('')); - const onEndListener = () => buildOutput$.complete(); + if (styles.length > 0) { + const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errMsg); + } - const onErrorListener = e => buildOutput$.error(e); + return chunks.join(''); +}; - stream.once('end', onEndListener); - stream.once('error', onErrorListener); - stream.on('data', onDataListener); - return rxjs__WEBPACK_IMPORTED_MODULE_0__["race"](getWatchHandlers(buildOutput$, opts)).pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["mergeMap"])(whenReady => whenReady), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["finalize"])(() => { - stream.removeListener('data', onDataListener); - stream.removeListener('end', onEndListener); - stream.removeListener('error', onErrorListener); - buildOutput$.complete(); - })).toPromise(); -} /***/ }), -/* 391 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 376 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(392); -/* 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__(393); -/* 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__(394); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__["buffer"]; }); +const restoreCursor = __webpack_require__(377); -/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(395); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__["bufferCount"]; }); +let isHidden = false; -/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(396); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__["bufferTime"]; }); +exports.show = (writableStream = process.stderr) => { + if (!writableStream.isTTY) { + return; + } -/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(397); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__["bufferToggle"]; }); + isHidden = false; + writableStream.write('\u001B[?25h'); +}; -/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(398); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__["bufferWhen"]; }); +exports.hide = (writableStream = process.stderr) => { + if (!writableStream.isTTY) { + return; + } -/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(399); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__["catchError"]; }); + restoreCursor(); + isHidden = true; + writableStream.write('\u001B[?25l'); +}; -/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(400); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__["combineAll"]; }); +exports.toggle = (force, writableStream) => { + if (force !== undefined) { + isHidden = force; + } -/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(401); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__["combineLatest"]; }); + if (isHidden) { + exports.show(writableStream); + } else { + exports.hide(writableStream); + } +}; -/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(402); -/* 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"]; }); +/***/ }), +/* 377 */ +/***/ (function(module, exports, __webpack_require__) { -/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(403); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__["concatMap"]; }); +"use strict"; -/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(404); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__["concatMapTo"]; }); +const onetime = __webpack_require__(378); +const signalExit = __webpack_require__(218); -/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(405); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "count", function() { return _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__["count"]; }); +module.exports = onetime(() => { + signalExit(() => { + process.stderr.write('\u001B[?25h'); + }, {alwaysLast: true}); +}); -/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(406); -/* 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__(407); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__["debounceTime"]; }); +/***/ }), +/* 378 */ +/***/ (function(module, exports, __webpack_require__) { -/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(408); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__["defaultIfEmpty"]; }); +"use strict"; -/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(409); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__["delay"]; }); +const mimicFn = __webpack_require__(379); -/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(411); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__["delayWhen"]; }); +const calledFunctions = new WeakMap(); -/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(412); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__["dematerialize"]; }); +const oneTime = (fn, options = {}) => { + if (typeof fn !== 'function') { + throw new TypeError('Expected a function'); + } -/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(413); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__["distinct"]; }); + let ret; + let isCalled = false; + let callCount = 0; + const functionName = fn.displayName || fn.name || ''; -/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(414); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__["distinctUntilChanged"]; }); + const onetime = function (...args) { + calledFunctions.set(onetime, ++callCount); -/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(415); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__["distinctUntilKeyChanged"]; }); + if (isCalled) { + if (options.throw === true) { + throw new Error(`Function \`${functionName}\` can only be called once`); + } -/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(416); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__["elementAt"]; }); + return ret; + } -/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(419); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__["endWith"]; }); + isCalled = true; + ret = fn.apply(this, args); + fn = null; -/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(420); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "every", function() { return _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__["every"]; }); + return ret; + }; -/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(421); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__["exhaust"]; }); + mimicFn(onetime, fn); + calledFunctions.set(onetime, callCount); -/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(422); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__["exhaustMap"]; }); + return onetime; +}; -/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(423); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__["expand"]; }); +module.exports = oneTime; +// TODO: Remove this for the next major release +module.exports.default = oneTime; -/* harmony import */ var _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(104); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__["filter"]; }); +module.exports.callCount = fn => { + if (!calledFunctions.has(fn)) { + throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); + } -/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(424); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__["finalize"]; }); + return calledFunctions.get(fn); +}; -/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(425); -/* 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__(426); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__["findIndex"]; }); +/***/ }), +/* 379 */ +/***/ (function(module, exports, __webpack_require__) { -/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(427); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "first", function() { return _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__["first"]; }); +"use strict"; -/* 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__(428); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__["ignoreElements"]; }); +const mimicFn = (to, from) => { + for (const prop of Reflect.ownKeys(from)) { + Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); + } -/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(429); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__["isEmpty"]; }); + return to; +}; -/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(430); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "last", function() { return _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__["last"]; }); +module.exports = mimicFn; +// TODO: Remove this for the next major release +module.exports.default = mimicFn; -/* 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__(432); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__["mapTo"]; }); +/***/ }), +/* 380 */ +/***/ (function(module, exports, __webpack_require__) { -/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(433); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__["materialize"]; }); +"use strict"; -/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(434); -/* 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__(437); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__["merge"]; }); +const spinners = Object.assign({}, __webpack_require__(381)); -/* harmony import */ var _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(81); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeAll", function() { return _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__["mergeAll"]; }); +const spinnersList = Object.keys(spinners); -/* 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"]; }); +Object.defineProperty(spinners, 'random', { + get() { + const randomIndex = Math.floor(Math.random() * spinnersList.length); + const spinnerName = spinnersList[randomIndex]; + return spinners[spinnerName]; + } +}); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); +module.exports = spinners; +// TODO: Remove this for the next major release +module.exports.default = spinners; -/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(438); -/* 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__(439); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__["mergeScan"]; }); +/***/ }), +/* 381 */ +/***/ (function(module) { -/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(440); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "min", function() { return _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__["min"]; }); +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\":[\"ρββββββ\",\"βρβββββ\",\"ββρββββ\",\"βββρβββ\",\"ββββρββ\",\"βββββρβ\",\"ββββββρ\"]}}"); -/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(441); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__["multicast"]; }); +/***/ }), +/* 382 */ +/***/ (function(module, exports, __webpack_require__) { -/* 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"]; }); +"use strict"; -/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(442); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__["onErrorResumeNext"]; }); +const chalk = __webpack_require__(383); -/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(443); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__["pairwise"]; }); +const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; -/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(444); -/* 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__(445); -/* 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__(446); -/* 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__(447); -/* 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__(448); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__["publishLast"]; }); +const main = { + info: chalk.blue('ℹ'), + success: chalk.green('✔'), + warning: chalk.yellow('⚠'), + error: chalk.red('✖') +}; -/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(449); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__["publishReplay"]; }); +const fallbacks = { + info: chalk.blue('i'), + success: chalk.green('√'), + warning: chalk.yellow('‼'), + error: chalk.red('×') +}; -/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(450); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__["race"]; }); +module.exports = isSupported ? main : fallbacks; -/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(435); -/* 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__(451); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__["repeat"]; }); +/***/ }), +/* 383 */ +/***/ (function(module, exports, __webpack_require__) { -/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(452); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__["repeatWhen"]; }); +"use strict"; -/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(453); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__["retry"]; }); +const escapeStringRegexp = __webpack_require__(179); +const ansiStyles = __webpack_require__(384); +const stdoutColor = __webpack_require__(389).stdout; -/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(454); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__["retryWhen"]; }); +const template = __webpack_require__(390); -/* 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"]; }); +const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); -/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(455); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__["sample"]; }); +// `supportsColor.level` → `ansiStyles.color[name]` mapping +const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; -/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(456); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__["sampleTime"]; }); +// `color-convert` models to exclude from the Chalk API due to conflicts and such +const skipModels = new Set(['gray']); -/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(436); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__["scan"]; }); +const styles = Object.create(null); -/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(457); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__["sequenceEqual"]; }); +function applyOptions(obj, options) { + options = options || {}; -/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(458); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "share", function() { return _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__["share"]; }); + // 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; +} -/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(459); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__["shareReplay"]; }); +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); -/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(460); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "single", function() { return _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__["single"]; }); + chalk.template = function () { + const args = [].slice.call(arguments); + return chalkTag.apply(null, [chalk.template].concat(args)); + }; -/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(461); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__["skip"]; }); + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); -/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(462); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__["skipLast"]; }); + chalk.template.constructor = Chalk; -/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(463); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__["skipUntil"]; }); + return chalk.template; + } -/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(464); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__["skipWhile"]; }); + applyOptions(this, options); +} -/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(465); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__["startWith"]; }); +// Use bright blue on Windows as the normal blue color is illegible +if (isSimpleWindowsTerm) { + ansiStyles.blue.open = '\u001B[94m'; +} -/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(466); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__["subscribeOn"]; }); +for (const key of Object.keys(ansiStyles)) { + ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); -/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(468); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__["switchAll"]; }); + styles[key] = { + get() { + const codes = ansiStyles[key]; + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + } + }; +} -/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(469); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__["switchMap"]; }); +styles.visible = { + get() { + return build.call(this, this._styles || [], true, 'visible'); + } +}; -/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(470); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__["switchMapTo"]; }); +ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); +for (const model of Object.keys(ansiStyles.color.ansi)) { + if (skipModels.has(model)) { + continue; + } -/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(418); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "take", function() { return _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__["take"]; }); + 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); + }; + } + }; +} -/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(431); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__["takeLast"]; }); +ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); +for (const model of Object.keys(ansiStyles.bgColor.ansi)) { + if (skipModels.has(model)) { + continue; + } -/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(471); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__["takeUntil"]; }); + 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); + }; + } + }; +} -/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(472); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__["takeWhile"]; }); +const proto = Object.defineProperties(() => {}, styles); -/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(473); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__["tap"]; }); +function build(_styles, _empty, key) { + const builder = function () { + return applyStyle.apply(builder, arguments); + }; -/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(474); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__["throttle"]; }); + builder._styles = _styles; + builder._empty = _empty; -/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(475); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__["throttleTime"]; }); + const self = this; -/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(417); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__["throwIfEmpty"]; }); + Object.defineProperty(builder, 'level', { + enumerable: true, + get() { + return self.level; + }, + set(level) { + self.level = level; + } + }); -/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(476); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__["timeInterval"]; }); + Object.defineProperty(builder, 'enabled', { + enumerable: true, + get() { + return self.enabled; + }, + set(enabled) { + self.enabled = enabled; + } + }); -/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(477); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__["timeout"]; }); + // See below for fix regarding invisible grey/dim combination on Windows + builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; -/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(478); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__["timeoutWith"]; }); + // `__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 -/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(479); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__["timestamp"]; }); + return builder; +} -/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(480); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__["toArray"]; }); +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]); -/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(481); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "window", function() { return _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__["window"]; }); + if (argsLen === 0) { + return ''; + } -/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(482); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__["windowCount"]; }); + if (argsLen > 1) { + // Don't slice `arguments`, it prevents V8 optimizations + for (let a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } -/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(483); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__["windowTime"]; }); + if (!this.enabled || this.level <= 0 || !str) { + return this._empty ? '' : str; + } -/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(484); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__["windowToggle"]; }); + // 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 = ''; + } -/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(485); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__["windowWhen"]; }); + 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; -/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(486); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__["withLatestFrom"]; }); + // 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}`); + } -/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(487); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__["zip"]; }); + // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue + ansiStyles.dim.open = originalDim; -/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(488); -/* 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 */ + 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); +module.exports = Chalk(); // eslint-disable-line new-cap +module.exports.supportsColor = stdoutColor; +module.exports.default = module.exports; // For TypeScript +/***/ }), +/* 384 */ +/***/ (function(module, exports, __webpack_require__) { +"use strict"; +/* WEBPACK VAR INJECTION */(function(module) { +const colorConvert = __webpack_require__(385); +const wrapAnsi16 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${code + offset}m`; +}; +const wrapAnsi256 = (fn, offset) => function () { + const code = fn.apply(colorConvert, arguments); + return `\u001B[${38 + offset};5;${code}m`; +}; +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__(115)(module))) +/***/ }), +/* 385 */ +/***/ (function(module, exports, __webpack_require__) { +var conversions = __webpack_require__(386); +var route = __webpack_require__(388); +var convert = {}; +var models = Object.keys(conversions); +function wrapRaw(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } + return fn(args); + }; + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } + return wrappedFn; +} +function wrapRounded(fn) { + var wrappedFn = function (args) { + if (args === undefined || args === null) { + return args; + } + if (arguments.length > 1) { + args = Array.prototype.slice.call(arguments); + } + var result = fn(args); + // 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 (var len = result.length, i = 0; i < len; i++) { + result[i] = Math.round(result[i]); + } + } + return result; + }; + // preserve .conversion property if there is one + if ('conversion' in fn) { + wrappedFn.conversion = fn.conversion; + } + return wrappedFn; +} +models.forEach(function (fromModel) { + convert[fromModel] = {}; + Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels}); + Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels}); + var routes = route(fromModel); + var routeModels = Object.keys(routes); + routeModels.forEach(function (toModel) { + var fn = routes[toModel]; + convert[fromModel][toModel] = wrapRounded(fn); + convert[fromModel][toModel].raw = wrapRaw(fn); + }); +}); +module.exports = convert; +/***/ }), +/* 386 */ +/***/ (function(module, exports, __webpack_require__) { +/* MIT license */ +var cssKeywords = __webpack_require__(387); +// 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.) +var reverseKeywords = {}; +for (var key in cssKeywords) { + if (cssKeywords.hasOwnProperty(key)) { + reverseKeywords[cssKeywords[key]] = key; + } +} +var convert = module.exports = { + 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']} +}; +// hide .channels and .labels properties +for (var model in convert) { + if (convert.hasOwnProperty(model)) { + if (!('channels' in convert[model])) { + throw new Error('missing channels property: ' + model); + } + if (!('labels' in convert[model])) { + throw new Error('missing channel labels property: ' + model); + } + if (convert[model].labels.length !== convert[model].channels) { + throw new Error('channel and label counts mismatch: ' + model); + } + var channels = convert[model].channels; + var labels = convert[model].labels; + delete convert[model].channels; + delete convert[model].labels; + Object.defineProperty(convert[model], 'channels', {value: channels}); + Object.defineProperty(convert[model], 'labels', {value: labels}); + } +} +convert.rgb.hsl = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var min = Math.min(r, g, b); + var max = Math.max(r, g, b); + var delta = max - min; + var h; + var s; + var l; + 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; + } + h = Math.min(h * 60, 360); + if (h < 0) { + h += 360; + } + l = (min + max) / 2; + if (max === min) { + s = 0; + } else if (l <= 0.5) { + s = delta / (max + min); + } else { + s = delta / (2 - max - min); + } + return [h, s * 100, l * 100]; +}; +convert.rgb.hsv = function (rgb) { + var rdif; + var gdif; + var bdif; + var h; + var s; + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var v = Math.max(r, g, b); + var diff = v - Math.min(r, g, b); + var diffc = function (c) { + return (v - c) / 6 / diff + 1 / 2; + }; + if (diff === 0) { + h = s = 0; + } else { + s = diff / v; + rdif = diffc(r); + gdif = diffc(g); + bdif = diffc(b); + if (r === v) { + h = bdif - gdif; + } else if (g === v) { + h = (1 / 3) + rdif - bdif; + } else if (b === v) { + h = (2 / 3) + gdif - rdif; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } + return [ + h * 360, + s * 100, + v * 100 + ]; +}; +convert.rgb.hwb = function (rgb) { + var r = rgb[0]; + var g = rgb[1]; + var b = rgb[2]; + var h = convert.rgb.hsl(rgb)[0]; + var w = 1 / 255 * Math.min(r, Math.min(g, b)); + b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); + return [h, w * 100, b * 100]; +}; +convert.rgb.cmyk = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var c; + var m; + var y; + var k; + k = Math.min(1 - r, 1 - g, 1 - b); + c = (1 - r - k) / (1 - k) || 0; + m = (1 - g - k) / (1 - k) || 0; + y = (1 - b - k) / (1 - k) || 0; + return [c * 100, m * 100, y * 100, k * 100]; +}; +/** + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + * */ +function comparativeDistance(x, y) { + return ( + Math.pow(x[0] - y[0], 2) + + Math.pow(x[1] - y[1], 2) + + Math.pow(x[2] - y[2], 2) + ); +} +convert.rgb.keyword = function (rgb) { + var reversed = reverseKeywords[rgb]; + if (reversed) { + return reversed; + } + var currentClosestDistance = Infinity; + var currentClosestKeyword; + for (var keyword in cssKeywords) { + if (cssKeywords.hasOwnProperty(keyword)) { + var value = cssKeywords[keyword]; + // Compute comparative distance + var distance = comparativeDistance(rgb, value); + // Check if its less, if so set as closest + if (distance < currentClosestDistance) { + currentClosestDistance = distance; + currentClosestKeyword = keyword; + } + } + } + return currentClosestKeyword; +}; +convert.keyword.rgb = function (keyword) { + return cssKeywords[keyword]; +}; +convert.rgb.xyz = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + // assume sRGB + r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); + g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); + b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); + var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); + var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); + var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); + return [x * 100, y * 100, z * 100]; +}; +convert.rgb.lab = function (rgb) { + var xyz = convert.rgb.xyz(rgb); + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; + x /= 95.047; + y /= 100; + z /= 108.883; + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + return [l, a, b]; +}; -//# sourceMappingURL=index.js.map +convert.hsl.rgb = function (hsl) { + var h = hsl[0] / 360; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var t1; + var t2; + var t3; + var rgb; + var val; + if (s === 0) { + val = l * 255; + return [val, val, val]; + } -/***/ }), -/* 392 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + if (l < 0.5) { + t2 = l * (1 + s); + } else { + t2 = l + s - l * s; + } -"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 */ + t1 = 2 * l - t2; + rgb = [0, 0, 0]; + for (var i = 0; i < 3; i++) { + t3 = h + 1 / 3 * -(i - 1); + if (t3 < 0) { + t3++; + } + if (t3 > 1) { + t3--; + } + 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 audit(durationSelector) { - return function auditOperatorFunction(source) { - return source.lift(new AuditOperator(durationSelector)); - }; -} -var AuditOperator = /*@__PURE__*/ (function () { - function AuditOperator(durationSelector) { - this.durationSelector = durationSelector; - } - AuditOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new AuditSubscriber(subscriber, this.durationSelector)); - }; - return AuditOperator; -}()); -var AuditSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AuditSubscriber, _super); - function AuditSubscriber(destination, durationSelector) { - var _this = _super.call(this, destination) || this; - _this.durationSelector = durationSelector; - _this.hasValue = false; - return _this; - } - AuditSubscriber.prototype._next = function (value) { - this.value = value; - this.hasValue = true; - if (!this.throttled) { - var duration = void 0; - try { - var durationSelector = this.durationSelector; - duration = durationSelector(value); - } - catch (err) { - return this.destination.error(err); - } - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration); - if (!innerSubscription || innerSubscription.closed) { - this.clearThrottle(); - } - else { - this.add(this.throttled = innerSubscription); - } - } - }; - AuditSubscriber.prototype.clearThrottle = function () { - var _a = this, value = _a.value, hasValue = _a.hasValue, throttled = _a.throttled; - if (throttled) { - this.remove(throttled); - this.throttled = null; - throttled.unsubscribe(); - } - if (hasValue) { - this.value = null; - this.hasValue = false; - this.destination.next(value); - } - }; - AuditSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex) { - this.clearThrottle(); - }; - AuditSubscriber.prototype.notifyComplete = function () { - this.clearThrottle(); - }; - return AuditSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=audit.js.map + rgb[i] = val * 255; + } + return rgb; +}; -/***/ }), -/* 393 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +convert.hsl.hsv = function (hsl) { + var h = hsl[0]; + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var smin = s; + var lmin = Math.max(l, 0.01); + var sv; + var v; -"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__(392); -/* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(107); -/** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ + l *= 2; + s *= (l <= 1) ? l : 2 - l; + smin *= lmin <= 1 ? lmin : 2 - lmin; + v = (l + s) / 2; + sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); + return [h, sv * 100, v * 100]; +}; +convert.hsv.rgb = function (hsv) { + var h = hsv[0] / 60; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var hi = Math.floor(h) % 6; -function auditTime(duration, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; - } - return Object(_audit__WEBPACK_IMPORTED_MODULE_1__["audit"])(function () { return Object(_observable_timer__WEBPACK_IMPORTED_MODULE_2__["timer"])(duration, scheduler); }); -} -//# sourceMappingURL=auditTime.js.map + var f = h - Math.floor(h); + var p = 255 * v * (1 - s); + var q = 255 * v * (1 - (s * f)); + var t = 255 * v * (1 - (s * (1 - f))); + v *= 255; + 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]; + } +}; -/***/ }), -/* 394 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +convert.hsv.hsl = function (hsv) { + var h = hsv[0]; + var s = hsv[1] / 100; + var v = hsv[2] / 100; + var vmin = Math.max(v, 0.01); + var lmin; + var sl; + var l; -"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 */ + l = (2 - s) * v; + lmin = (2 - s) * vmin; + sl = s * vmin; + sl /= (lmin <= 1) ? lmin : 2 - lmin; + sl = sl || 0; + l /= 2; + return [h, sl * 100, l * 100]; +}; +// http://dev.w3.org/csswg/css-color/#hwb-to-rgb +convert.hwb.rgb = function (hwb) { + var h = hwb[0] / 360; + var wh = hwb[1] / 100; + var bl = hwb[2] / 100; + var ratio = wh + bl; + var i; + var v; + var f; + var n; -function buffer(closingNotifier) { - return function bufferOperatorFunction(source) { - return source.lift(new BufferOperator(closingNotifier)); - }; -} -var BufferOperator = /*@__PURE__*/ (function () { - function BufferOperator(closingNotifier) { - this.closingNotifier = closingNotifier; - } - BufferOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new BufferSubscriber(subscriber, this.closingNotifier)); - }; - return BufferOperator; -}()); -var BufferSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferSubscriber, _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)); - return _this; - } - BufferSubscriber.prototype._next = function (value) { - this.buffer.push(value); - }; - BufferSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - var buffer = this.buffer; - this.buffer = []; - this.destination.next(buffer); - }; - return BufferSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=buffer.js.map + // wh + bl cant be > 1 + if (ratio > 1) { + wh /= ratio; + bl /= ratio; + } + i = Math.floor(6 * h); + v = 1 - bl; + f = 6 * h - i; -/***/ }), -/* 395 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + if ((i & 0x01) !== 0) { + f = 1 - f; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return bufferCount; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + n = wh + f * (v - wh); // linear interpolation + var r; + var g; + var b; + 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; + } -function bufferCount(bufferSize, startBufferEvery) { - if (startBufferEvery === void 0) { - startBufferEvery = null; - } - return function bufferCountOperatorFunction(source) { - return source.lift(new BufferCountOperator(bufferSize, startBufferEvery)); - }; -} -var BufferCountOperator = /*@__PURE__*/ (function () { - function BufferCountOperator(bufferSize, startBufferEvery) { - this.bufferSize = bufferSize; - this.startBufferEvery = startBufferEvery; - if (!startBufferEvery || bufferSize === startBufferEvery) { - this.subscriberClass = BufferCountSubscriber; - } - else { - this.subscriberClass = BufferSkipCountSubscriber; - } - } - BufferCountOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new this.subscriberClass(subscriber, this.bufferSize, this.startBufferEvery)); - }; - return BufferCountOperator; -}()); -var BufferCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferCountSubscriber, _super); - function BufferCountSubscriber(destination, bufferSize) { - var _this = _super.call(this, destination) || this; - _this.bufferSize = bufferSize; - _this.buffer = []; - return _this; - } - BufferCountSubscriber.prototype._next = function (value) { - var buffer = this.buffer; - buffer.push(value); - if (buffer.length == this.bufferSize) { - this.destination.next(buffer); - this.buffer = []; - } - }; - BufferCountSubscriber.prototype._complete = function () { - var buffer = this.buffer; - if (buffer.length > 0) { - this.destination.next(buffer); - } - _super.prototype._complete.call(this); - }; - return BufferCountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -var BufferSkipCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferSkipCountSubscriber, _super); - function BufferSkipCountSubscriber(destination, bufferSize, startBufferEvery) { - var _this = _super.call(this, destination) || this; - _this.bufferSize = bufferSize; - _this.startBufferEvery = startBufferEvery; - _this.buffers = []; - _this.count = 0; - return _this; - } - BufferSkipCountSubscriber.prototype._next = function (value) { - var _a = this, bufferSize = _a.bufferSize, startBufferEvery = _a.startBufferEvery, buffers = _a.buffers, count = _a.count; - this.count++; - if (count % startBufferEvery === 0) { - buffers.push([]); - } - for (var i = buffers.length; i--;) { - var buffer = buffers[i]; - buffer.push(value); - if (buffer.length === bufferSize) { - buffers.splice(i, 1); - this.destination.next(buffer); - } - } - }; - BufferSkipCountSubscriber.prototype._complete = function () { - var _a = this, buffers = _a.buffers, destination = _a.destination; - while (buffers.length > 0) { - var buffer = buffers.shift(); - if (buffer.length > 0) { - destination.next(buffer); - } - } - _super.prototype._complete.call(this); - }; - return BufferSkipCountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=bufferCount.js.map + return [r * 255, g * 255, b * 255]; +}; +convert.cmyk.rgb = function (cmyk) { + var c = cmyk[0] / 100; + var m = cmyk[1] / 100; + var y = cmyk[2] / 100; + var k = cmyk[3] / 100; + var r; + var g; + var b; -/***/ }), -/* 396 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + r = 1 - Math.min(1, c * (1 - k) + k); + g = 1 - Math.min(1, m * (1 - k) + k); + b = 1 - Math.min(1, y * (1 - k) + k); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return bufferTime; }); -/* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(45); -/** PURE_IMPORTS_START tslib,_scheduler_async,_Subscriber,_util_isScheduler PURE_IMPORTS_END */ + return [r * 255, g * 255, b * 255]; +}; +convert.xyz.rgb = function (xyz) { + var x = xyz[0] / 100; + var y = xyz[1] / 100; + var z = xyz[2] / 100; + var r; + var g; + var b; + 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); + // assume sRGB + r = r > 0.0031308 + ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) + : r * 12.92; -function bufferTime(bufferTimeSpan) { - var length = arguments.length; - var scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_3__["isScheduler"])(arguments[arguments.length - 1])) { - scheduler = arguments[arguments.length - 1]; - length--; - } - var bufferCreationInterval = null; - if (length >= 2) { - bufferCreationInterval = arguments[1]; - } - var maxBufferSize = Number.POSITIVE_INFINITY; - if (length >= 3) { - maxBufferSize = arguments[2]; - } - return function bufferTimeOperatorFunction(source) { - return source.lift(new BufferTimeOperator(bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler)); - }; -} -var BufferTimeOperator = /*@__PURE__*/ (function () { - function BufferTimeOperator(bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler) { - this.bufferTimeSpan = bufferTimeSpan; - this.bufferCreationInterval = bufferCreationInterval; - this.maxBufferSize = maxBufferSize; - this.scheduler = scheduler; - } - BufferTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new BufferTimeSubscriber(subscriber, this.bufferTimeSpan, this.bufferCreationInterval, this.maxBufferSize, this.scheduler)); - }; - return BufferTimeOperator; -}()); -var Context = /*@__PURE__*/ (function () { - function Context() { - this.buffer = []; - } - return Context; -}()); -var BufferTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferTimeSubscriber, _super); - function BufferTimeSubscriber(destination, bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler) { - var _this = _super.call(this, destination) || this; - _this.bufferTimeSpan = bufferTimeSpan; - _this.bufferCreationInterval = bufferCreationInterval; - _this.maxBufferSize = maxBufferSize; - _this.scheduler = scheduler; - _this.contexts = []; - var context = _this.openContext(); - _this.timespanOnly = bufferCreationInterval == null || bufferCreationInterval < 0; - if (_this.timespanOnly) { - var timeSpanOnlyState = { subscriber: _this, context: context, bufferTimeSpan: bufferTimeSpan }; - _this.add(context.closeAction = scheduler.schedule(dispatchBufferTimeSpanOnly, bufferTimeSpan, timeSpanOnlyState)); - } - else { - var closeState = { subscriber: _this, context: context }; - var creationState = { bufferTimeSpan: bufferTimeSpan, bufferCreationInterval: bufferCreationInterval, subscriber: _this, scheduler: scheduler }; - _this.add(context.closeAction = scheduler.schedule(dispatchBufferClose, bufferTimeSpan, closeState)); - _this.add(scheduler.schedule(dispatchBufferCreation, bufferCreationInterval, creationState)); - } - return _this; - } - BufferTimeSubscriber.prototype._next = function (value) { - var contexts = this.contexts; - var len = contexts.length; - var filledBufferContext; - for (var i = 0; i < len; i++) { - var context_1 = contexts[i]; - var buffer = context_1.buffer; - buffer.push(value); - if (buffer.length == this.maxBufferSize) { - filledBufferContext = context_1; - } - } - if (filledBufferContext) { - this.onBufferFull(filledBufferContext); - } - }; - BufferTimeSubscriber.prototype._error = function (err) { - this.contexts.length = 0; - _super.prototype._error.call(this, err); - }; - BufferTimeSubscriber.prototype._complete = function () { - var _a = this, contexts = _a.contexts, destination = _a.destination; - while (contexts.length > 0) { - var context_2 = contexts.shift(); - destination.next(context_2.buffer); - } - _super.prototype._complete.call(this); - }; - BufferTimeSubscriber.prototype._unsubscribe = function () { - this.contexts = null; - }; - BufferTimeSubscriber.prototype.onBufferFull = function (context) { - this.closeContext(context); - var closeAction = context.closeAction; - closeAction.unsubscribe(); - this.remove(closeAction); - if (!this.closed && this.timespanOnly) { - context = this.openContext(); - var bufferTimeSpan = this.bufferTimeSpan; - var timeSpanOnlyState = { subscriber: this, context: context, bufferTimeSpan: bufferTimeSpan }; - this.add(context.closeAction = this.scheduler.schedule(dispatchBufferTimeSpanOnly, bufferTimeSpan, timeSpanOnlyState)); - } - }; - BufferTimeSubscriber.prototype.openContext = function () { - var context = new Context(); - this.contexts.push(context); - return context; - }; - BufferTimeSubscriber.prototype.closeContext = function (context) { - this.destination.next(context.buffer); - var contexts = this.contexts; - var spliceIndex = contexts ? contexts.indexOf(context) : -1; - if (spliceIndex >= 0) { - contexts.splice(contexts.indexOf(context), 1); - } - }; - return BufferTimeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); -function dispatchBufferTimeSpanOnly(state) { - var subscriber = state.subscriber; - var prevContext = state.context; - if (prevContext) { - subscriber.closeContext(prevContext); - } - if (!subscriber.closed) { - state.context = subscriber.openContext(); - state.context.closeAction = this.schedule(state, state.bufferTimeSpan); - } -} -function dispatchBufferCreation(state) { - var bufferCreationInterval = state.bufferCreationInterval, bufferTimeSpan = state.bufferTimeSpan, subscriber = state.subscriber, scheduler = state.scheduler; - var context = subscriber.openContext(); - var action = this; - if (!subscriber.closed) { - subscriber.add(context.closeAction = scheduler.schedule(dispatchBufferClose, bufferTimeSpan, { subscriber: subscriber, context: context })); - action.schedule(state, bufferCreationInterval); - } -} -function dispatchBufferClose(arg) { - var subscriber = arg.subscriber, context = arg.context; - subscriber.closeContext(context); -} -//# sourceMappingURL=bufferTime.js.map + g = g > 0.0031308 + ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) + : g * 12.92; + b = b > 0.0031308 + ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) + : b * 12.92; -/***/ }), -/* 397 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return bufferToggle; }); -/* 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 _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); -/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69); -/** PURE_IMPORTS_START tslib,_Subscription,_util_subscribeToResult,_OuterSubscriber PURE_IMPORTS_END */ + return [r * 255, g * 255, b * 255]; +}; +convert.xyz.lab = function (xyz) { + var x = xyz[0]; + var y = xyz[1]; + var z = xyz[2]; + var l; + var a; + var b; + x /= 95.047; + y /= 100; + z /= 108.883; + x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); + y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); + z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); -function bufferToggle(openings, closingSelector) { - return function bufferToggleOperatorFunction(source) { - return source.lift(new BufferToggleOperator(openings, closingSelector)); - }; -} -var BufferToggleOperator = /*@__PURE__*/ (function () { - function BufferToggleOperator(openings, closingSelector) { - this.openings = openings; - this.closingSelector = closingSelector; - } - BufferToggleOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new BufferToggleSubscriber(subscriber, this.openings, this.closingSelector)); - }; - return BufferToggleOperator; -}()); -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)); - return _this; - } - BufferToggleSubscriber.prototype._next = function (value) { - var contexts = this.contexts; - var len = contexts.length; - for (var i = 0; i < len; i++) { - contexts[i].buffer.push(value); - } - }; - BufferToggleSubscriber.prototype._error = function (err) { - var contexts = this.contexts; - while (contexts.length > 0) { - var context_1 = contexts.shift(); - context_1.subscription.unsubscribe(); - context_1.buffer = null; - context_1.subscription = null; - } - this.contexts = null; - _super.prototype._error.call(this, err); - }; - BufferToggleSubscriber.prototype._complete = function () { - var contexts = this.contexts; - while (contexts.length > 0) { - var context_2 = contexts.shift(); - this.destination.next(context_2.buffer); - context_2.subscription.unsubscribe(); - context_2.buffer = null; - context_2.subscription = null; - } - this.contexts = null; - _super.prototype._complete.call(this); - }; - BufferToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - outerValue ? this.closeBuffer(outerValue) : this.openBuffer(innerValue); - }; - BufferToggleSubscriber.prototype.notifyComplete = function (innerSub) { - this.closeBuffer(innerSub.context); - }; - BufferToggleSubscriber.prototype.openBuffer = function (value) { - try { - var closingSelector = this.closingSelector; - var closingNotifier = closingSelector.call(this, value); - if (closingNotifier) { - this.trySubscribe(closingNotifier); - } - } - catch (err) { - this._error(err); - } - }; - BufferToggleSubscriber.prototype.closeBuffer = function (context) { - var contexts = this.contexts; - if (contexts && context) { - var buffer = context.buffer, subscription = context.subscription; - this.destination.next(buffer); - contexts.splice(contexts.indexOf(context), 1); - this.remove(subscription); - subscription.unsubscribe(); - } - }; - BufferToggleSubscriber.prototype.trySubscribe = function (closingNotifier) { - var contexts = this.contexts; - var buffer = []; - var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); - var context = { buffer: buffer, subscription: subscription }; - contexts.push(context); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, closingNotifier, context); - if (!innerSubscription || innerSubscription.closed) { - this.closeBuffer(context); - } - else { - innerSubscription.context = context; - this.add(innerSubscription); - subscription.add(innerSubscription); - } - }; - return BufferToggleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -//# sourceMappingURL=bufferToggle.js.map + l = (116 * y) - 16; + a = 500 * (x - y); + b = 200 * (y - z); + return [l, a, b]; +}; -/***/ }), -/* 398 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +convert.lab.xyz = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var x; + var y; + var z; -"use strict"; -__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 */ + y = (l + 16) / 116; + x = a / 500 + y; + z = y - b / 200; + var y2 = Math.pow(y, 3); + var x2 = Math.pow(x, 3); + var z2 = Math.pow(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; + x *= 95.047; + y *= 100; + z *= 108.883; + return [x, y, z]; +}; -function bufferWhen(closingSelector) { - return function (source) { - return source.lift(new BufferWhenOperator(closingSelector)); - }; -} -var BufferWhenOperator = /*@__PURE__*/ (function () { - function BufferWhenOperator(closingSelector) { - this.closingSelector = closingSelector; - } - BufferWhenOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new BufferWhenSubscriber(subscriber, this.closingSelector)); - }; - return BufferWhenOperator; -}()); -var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferWhenSubscriber, _super); - function BufferWhenSubscriber(destination, closingSelector) { - var _this = _super.call(this, destination) || this; - _this.closingSelector = closingSelector; - _this.subscribing = false; - _this.openBuffer(); - return _this; - } - BufferWhenSubscriber.prototype._next = function (value) { - this.buffer.push(value); - }; - BufferWhenSubscriber.prototype._complete = function () { - var buffer = this.buffer; - if (buffer) { - this.destination.next(buffer); - } - _super.prototype._complete.call(this); - }; - BufferWhenSubscriber.prototype._unsubscribe = function () { - this.buffer = null; - this.subscribing = false; - }; - BufferWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.openBuffer(); - }; - BufferWhenSubscriber.prototype.notifyComplete = function () { - if (this.subscribing) { - this.complete(); - } - else { - this.openBuffer(); - } - }; - BufferWhenSubscriber.prototype.openBuffer = function () { - var closingSubscription = this.closingSubscription; - if (closingSubscription) { - this.remove(closingSubscription); - closingSubscription.unsubscribe(); - } - var buffer = this.buffer; - if (this.buffer) { - this.destination.next(buffer); - } - this.buffer = []; - var closingNotifier; - try { - var closingSelector = this.closingSelector; - closingNotifier = closingSelector(); - } - catch (err) { - return this.error(err); - } - closingSubscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); - this.closingSubscription = closingSubscription; - this.add(closingSubscription); - this.subscribing = true; - closingSubscription.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, closingNotifier)); - this.subscribing = false; - }; - return BufferWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=bufferWhen.js.map +convert.lab.lch = function (lab) { + var l = lab[0]; + var a = lab[1]; + var b = lab[2]; + var hr; + var h; + var c; + hr = Math.atan2(b, a); + h = hr * 360 / 2 / Math.PI; -/***/ }), -/* 399 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + if (h < 0) { + h += 360; + } -"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 */ + c = Math.sqrt(a * a + b * b); + return [l, c, h]; +}; +convert.lch.lab = function (lch) { + var l = lch[0]; + var c = lch[1]; + var h = lch[2]; + var a; + var b; + var hr; + hr = h / 360 * 2 * Math.PI; + a = c * Math.cos(hr); + b = c * Math.sin(hr); -function catchError(selector) { - return function catchErrorOperatorFunction(source) { - var operator = new CatchOperator(selector); - var caught = source.lift(operator); - return (operator.caught = caught); - }; -} -var CatchOperator = /*@__PURE__*/ (function () { - function CatchOperator(selector) { - this.selector = selector; - } - CatchOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new CatchSubscriber(subscriber, this.selector, this.caught)); - }; - return CatchOperator; -}()); -var CatchSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CatchSubscriber, _super); - function CatchSubscriber(destination, selector, caught) { - var _this = _super.call(this, destination) || this; - _this.selector = selector; - _this.caught = caught; - return _this; - } - CatchSubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var result = void 0; - try { - result = this.selector(err, this.caught); - } - catch (err2) { - _super.prototype.error.call(this, err2); - return; - } - this._unsubscribeAndRecycle(); - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, undefined, undefined); - this.add(innerSubscriber); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, undefined, undefined, innerSubscriber); - if (innerSubscription !== innerSubscriber) { - this.add(innerSubscription); - } - } - }; - return CatchSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=catchError.js.map + return [l, a, b]; +}; +convert.rgb.ansi16 = function (args) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization -/***/ }), -/* 400 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + value = Math.round(value / 50); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return combineAll; }); -/* harmony import */ var _observable_combineLatest__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(68); -/** PURE_IMPORTS_START _observable_combineLatest PURE_IMPORTS_END */ + if (value === 0) { + return 30; + } -function combineAll(project) { - return function (source) { return source.lift(new _observable_combineLatest__WEBPACK_IMPORTED_MODULE_0__["CombineLatestOperator"](project)); }; -} -//# sourceMappingURL=combineAll.js.map + var ansi = 30 + + ((Math.round(b / 255) << 2) + | (Math.round(g / 255) << 1) + | Math.round(r / 255)); + if (value === 2) { + ansi += 60; + } -/***/ }), -/* 401 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + return ansi; +}; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return combineLatest; }); -/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18); -/* harmony import */ var _observable_combineLatest__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68); -/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(83); -/** PURE_IMPORTS_START _util_isArray,_observable_combineLatest,_observable_from PURE_IMPORTS_END */ +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) { + var r = args[0]; + var g = args[1]; + var b = args[2]; + // 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; + } -var none = {}; -function combineLatest() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - var project = null; - if (typeof observables[observables.length - 1] === 'function') { - project = observables.pop(); - } - if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(observables[0])) { - observables = observables[0].slice(); - } - return function (source) { return source.lift.call(Object(_observable_from__WEBPACK_IMPORTED_MODULE_2__["from"])([source].concat(observables)), new _observable_combineLatest__WEBPACK_IMPORTED_MODULE_1__["CombineLatestOperator"](project)); }; -} -//# sourceMappingURL=combineLatest.js.map + if (r > 248) { + return 231; + } + return Math.round(((r - 8) / 247) * 24) + 232; + } -/***/ }), -/* 402 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + var ansi = 16 + + (36 * Math.round(r / 255 * 5)) + + (6 * Math.round(g / 255 * 5)) + + Math.round(b / 255 * 5); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return concat; }); -/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(79); -/** PURE_IMPORTS_START _observable_concat PURE_IMPORTS_END */ + return ansi; +}; -function concat() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - return function (source) { return source.lift.call(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"].apply(void 0, [source].concat(observables))); }; -} -//# sourceMappingURL=concat.js.map +convert.ansi16.rgb = function (args) { + var color = args % 10; + // handle greyscale + if (color === 0 || color === 7) { + if (args > 50) { + color += 3.5; + } -/***/ }), -/* 403 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + color = color / 10.5 * 255; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return concatMap; }); -/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82); -/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ + return [color, color, color]; + } -function concatMap(project, resultSelector) { - return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(project, resultSelector, 1); -} -//# sourceMappingURL=concatMap.js.map + var mult = (~~(args > 50) + 1) * 0.5; + var r = ((color & 1) * mult) * 255; + var g = (((color >> 1) & 1) * mult) * 255; + var b = (((color >> 2) & 1) * mult) * 255; + return [r, g, b]; +}; -/***/ }), -/* 404 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +convert.ansi256.rgb = function (args) { + // handle greyscale + if (args >= 232) { + var c = (args - 232) * 10 + 8; + return [c, c, c]; + } -"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__(403); -/** PURE_IMPORTS_START _concatMap PURE_IMPORTS_END */ + args -= 16; -function concatMapTo(innerObservable, resultSelector) { - return Object(_concatMap__WEBPACK_IMPORTED_MODULE_0__["concatMap"])(function () { return innerObservable; }, resultSelector); -} -//# sourceMappingURL=concatMapTo.js.map + var rem; + var r = Math.floor(args / 36) / 5 * 255; + var g = Math.floor((rem = args % 36) / 6) / 5 * 255; + var b = (rem % 6) / 5 * 255; + return [r, g, b]; +}; -/***/ }), -/* 405 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +convert.rgb.hex = function (args) { + var integer = ((Math.round(args[0]) & 0xFF) << 16) + + ((Math.round(args[1]) & 0xFF) << 8) + + (Math.round(args[2]) & 0xFF); -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "count", function() { return count; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; +convert.hex.rgb = function (args) { + var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); + if (!match) { + return [0, 0, 0]; + } -function count(predicate) { - return function (source) { return source.lift(new CountOperator(predicate, source)); }; -} -var CountOperator = /*@__PURE__*/ (function () { - function CountOperator(predicate, source) { - this.predicate = predicate; - this.source = source; - } - CountOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new CountSubscriber(subscriber, this.predicate, this.source)); - }; - return CountOperator; -}()); -var CountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CountSubscriber, _super); - function CountSubscriber(destination, predicate, source) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.source = source; - _this.count = 0; - _this.index = 0; - return _this; - } - CountSubscriber.prototype._next = function (value) { - if (this.predicate) { - this._tryPredicate(value); - } - else { - this.count++; - } - }; - CountSubscriber.prototype._tryPredicate = function (value) { - var result; - try { - result = this.predicate(value, this.index++, this.source); - } - catch (err) { - this.destination.error(err); - return; - } - if (result) { - this.count++; - } - }; - CountSubscriber.prototype._complete = function () { - this.destination.next(this.count); - this.destination.complete(); - }; - return CountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=count.js.map + var colorString = match[0]; + if (match[0].length === 3) { + colorString = colorString.split('').map(function (char) { + return char + char; + }).join(''); + } -/***/ }), -/* 406 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + var integer = parseInt(colorString, 16); + var r = (integer >> 16) & 0xFF; + var g = (integer >> 8) & 0xFF; + var b = integer & 0xFF; -"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 */ + return [r, g, b]; +}; +convert.rgb.hcg = function (rgb) { + var r = rgb[0] / 255; + var g = rgb[1] / 255; + var b = rgb[2] / 255; + var max = Math.max(Math.max(r, g), b); + var min = Math.min(Math.min(r, g), b); + var chroma = (max - min); + var grayscale; + var hue; + if (chroma < 1) { + grayscale = min / (1 - chroma); + } else { + grayscale = 0; + } -function debounce(durationSelector) { - return function (source) { return source.lift(new DebounceOperator(durationSelector)); }; -} -var DebounceOperator = /*@__PURE__*/ (function () { - function DebounceOperator(durationSelector) { - this.durationSelector = durationSelector; - } - DebounceOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DebounceSubscriber(subscriber, this.durationSelector)); - }; - return DebounceOperator; -}()); -var DebounceSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DebounceSubscriber, _super); - function DebounceSubscriber(destination, durationSelector) { - var _this = _super.call(this, destination) || this; - _this.durationSelector = durationSelector; - _this.hasValue = false; - _this.durationSubscription = null; - return _this; - } - DebounceSubscriber.prototype._next = function (value) { - try { - var result = this.durationSelector.call(this, value); - if (result) { - this._tryNext(value, result); - } - } - catch (err) { - this.destination.error(err); - } - }; - DebounceSubscriber.prototype._complete = function () { - this.emitValue(); - this.destination.complete(); - }; - DebounceSubscriber.prototype._tryNext = function (value, duration) { - var subscription = this.durationSubscription; - this.value = value; - this.hasValue = true; - if (subscription) { - subscription.unsubscribe(); - this.remove(subscription); - } - subscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, duration); - if (subscription && !subscription.closed) { - this.add(this.durationSubscription = subscription); - } - }; - DebounceSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.emitValue(); - }; - DebounceSubscriber.prototype.notifyComplete = function () { - this.emitValue(); - }; - DebounceSubscriber.prototype.emitValue = function () { - if (this.hasValue) { - var value = this.value; - var subscription = this.durationSubscription; - if (subscription) { - this.durationSubscription = null; - subscription.unsubscribe(); - this.remove(subscription); - } - this.value = null; - this.hasValue = false; - _super.prototype._next.call(this, value); - } - }; - return DebounceSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=debounce.js.map + 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 + 4; + } + hue /= 6; + hue %= 1; -/***/ }), -/* 407 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + return [hue * 360, chroma * 100, grayscale * 100]; +}; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return debounceTime; }); -/* 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); -/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async PURE_IMPORTS_END */ +convert.hsl.hcg = function (hsl) { + var s = hsl[1] / 100; + var l = hsl[2] / 100; + var c = 1; + var f = 0; + if (l < 0.5) { + c = 2.0 * s * l; + } else { + c = 2.0 * s * (1.0 - l); + } + if (c < 1.0) { + f = (l - 0.5 * c) / (1.0 - c); + } -function debounceTime(dueTime, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; - } - return function (source) { return source.lift(new DebounceTimeOperator(dueTime, scheduler)); }; -} -var DebounceTimeOperator = /*@__PURE__*/ (function () { - function DebounceTimeOperator(dueTime, scheduler) { - this.dueTime = dueTime; - this.scheduler = scheduler; - } - DebounceTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DebounceTimeSubscriber(subscriber, this.dueTime, this.scheduler)); - }; - return DebounceTimeOperator; -}()); -var DebounceTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DebounceTimeSubscriber, _super); - function DebounceTimeSubscriber(destination, dueTime, scheduler) { - var _this = _super.call(this, destination) || this; - _this.dueTime = dueTime; - _this.scheduler = scheduler; - _this.debouncedSubscription = null; - _this.lastValue = null; - _this.hasValue = false; - return _this; - } - DebounceTimeSubscriber.prototype._next = function (value) { - this.clearDebounce(); - this.lastValue = value; - this.hasValue = true; - this.add(this.debouncedSubscription = this.scheduler.schedule(dispatchNext, this.dueTime, this)); - }; - DebounceTimeSubscriber.prototype._complete = function () { - this.debouncedNext(); - this.destination.complete(); - }; - DebounceTimeSubscriber.prototype.debouncedNext = function () { - this.clearDebounce(); - if (this.hasValue) { - var lastValue = this.lastValue; - this.lastValue = null; - this.hasValue = false; - this.destination.next(lastValue); - } - }; - DebounceTimeSubscriber.prototype.clearDebounce = function () { - var debouncedSubscription = this.debouncedSubscription; - if (debouncedSubscription !== null) { - this.remove(debouncedSubscription); - debouncedSubscription.unsubscribe(); - this.debouncedSubscription = null; - } - }; - return DebounceTimeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -function dispatchNext(subscriber) { - subscriber.debouncedNext(); -} -//# sourceMappingURL=debounceTime.js.map + return [hsl[0], c * 100, f * 100]; +}; +convert.hsv.hcg = function (hsv) { + var s = hsv[1] / 100; + var v = hsv[2] / 100; -/***/ }), -/* 408 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + var c = s * v; + var f = 0; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return defaultIfEmpty; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + if (c < 1.0) { + f = (v - c) / (1 - c); + } + return [hsv[0], c * 100, f * 100]; +}; -function defaultIfEmpty(defaultValue) { - if (defaultValue === void 0) { - defaultValue = null; - } - return function (source) { return source.lift(new DefaultIfEmptyOperator(defaultValue)); }; -} -var DefaultIfEmptyOperator = /*@__PURE__*/ (function () { - function DefaultIfEmptyOperator(defaultValue) { - this.defaultValue = defaultValue; - } - DefaultIfEmptyOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DefaultIfEmptySubscriber(subscriber, this.defaultValue)); - }; - return DefaultIfEmptyOperator; -}()); -var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DefaultIfEmptySubscriber, _super); - function DefaultIfEmptySubscriber(destination, defaultValue) { - var _this = _super.call(this, destination) || this; - _this.defaultValue = defaultValue; - _this.isEmpty = true; - return _this; - } - DefaultIfEmptySubscriber.prototype._next = function (value) { - this.isEmpty = false; - this.destination.next(value); - }; - DefaultIfEmptySubscriber.prototype._complete = function () { - if (this.isEmpty) { - this.destination.next(this.defaultValue); - } - this.destination.complete(); - }; - return DefaultIfEmptySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=defaultIfEmpty.js.map +convert.hcg.rgb = function (hcg) { + var h = hcg[0] / 360; + var c = hcg[1] / 100; + var g = hcg[2] / 100; + if (c === 0.0) { + return [g * 255, g * 255, g * 255]; + } -/***/ }), -/* 409 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + var pure = [0, 0, 0]; + var hi = (h % 1) * 6; + var v = hi % 1; + var w = 1 - v; + var mg = 0; -"use strict"; -__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__(410); -/* 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 */ + 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; + } + mg = (1.0 - c) * g; + + return [ + (c * pure[0] + mg) * 255, + (c * pure[1] + mg) * 255, + (c * pure[2] + mg) * 255 + ]; +}; + +convert.hcg.hsv = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + var v = c + g * (1.0 - c); + var f = 0; + + if (v > 0.0) { + f = c / v; + } + + return [hcg[0], f * 100, v * 100]; +}; + +convert.hcg.hsl = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + + var l = g * (1.0 - c) + 0.5 * c; + var s = 0; + + if (l > 0.0 && l < 0.5) { + s = c / (2 * l); + } else + if (l >= 0.5 && l < 1.0) { + s = c / (2 * (1 - l)); + } + + return [hcg[0], s * 100, l * 100]; +}; + +convert.hcg.hwb = function (hcg) { + var c = hcg[1] / 100; + var g = hcg[2] / 100; + var v = c + g * (1.0 - c); + return [hcg[0], (v - c) * 100, (1 - v) * 100]; +}; + +convert.hwb.hcg = function (hwb) { + var w = hwb[1] / 100; + var b = hwb[2] / 100; + var v = 1 - b; + var c = v - w; + var g = 0; + + if (c < 1) { + g = (v - c) / (1 - c); + } + + return [hwb[0], c * 100, g * 100]; +}; + +convert.apple.rgb = function (apple) { + return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; +}; + +convert.rgb.apple = function (rgb) { + return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; +}; + +convert.gray.rgb = function (args) { + return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; +}; + +convert.gray.hsl = convert.gray.hsv = function (args) { + return [0, 0, args[0]]; +}; + +convert.gray.hwb = function (gray) { + return [0, 100, gray[0]]; +}; + +convert.gray.cmyk = function (gray) { + return [0, 0, 0, gray[0]]; +}; + +convert.gray.lab = function (gray) { + return [gray[0], 0, 0]; +}; + +convert.gray.hex = function (gray) { + var val = Math.round(gray[0] / 100 * 255) & 0xFF; + var integer = (val << 16) + (val << 8) + val; + + var string = integer.toString(16).toUpperCase(); + return '000000'.substring(string.length) + string; +}; + +convert.rgb.gray = function (rgb) { + var val = (rgb[0] + rgb[1] + rgb[2]) / 3; + return [val / 255 * 100]; +}; + + +/***/ }), +/* 387 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +module.exports = { + "aliceblue": [240, 248, 255], + "antiquewhite": [250, 235, 215], + "aqua": [0, 255, 255], + "aquamarine": [127, 255, 212], + "azure": [240, 255, 255], + "beige": [245, 245, 220], + "bisque": [255, 228, 196], + "black": [0, 0, 0], + "blanchedalmond": [255, 235, 205], + "blue": [0, 0, 255], + "blueviolet": [138, 43, 226], + "brown": [165, 42, 42], + "burlywood": [222, 184, 135], + "cadetblue": [95, 158, 160], + "chartreuse": [127, 255, 0], + "chocolate": [210, 105, 30], + "coral": [255, 127, 80], + "cornflowerblue": [100, 149, 237], + "cornsilk": [255, 248, 220], + "crimson": [220, 20, 60], + "cyan": [0, 255, 255], + "darkblue": [0, 0, 139], + "darkcyan": [0, 139, 139], + "darkgoldenrod": [184, 134, 11], + "darkgray": [169, 169, 169], + "darkgreen": [0, 100, 0], + "darkgrey": [169, 169, 169], + "darkkhaki": [189, 183, 107], + "darkmagenta": [139, 0, 139], + "darkolivegreen": [85, 107, 47], + "darkorange": [255, 140, 0], + "darkorchid": [153, 50, 204], + "darkred": [139, 0, 0], + "darksalmon": [233, 150, 122], + "darkseagreen": [143, 188, 143], + "darkslateblue": [72, 61, 139], + "darkslategray": [47, 79, 79], + "darkslategrey": [47, 79, 79], + "darkturquoise": [0, 206, 209], + "darkviolet": [148, 0, 211], + "deeppink": [255, 20, 147], + "deepskyblue": [0, 191, 255], + "dimgray": [105, 105, 105], + "dimgrey": [105, 105, 105], + "dodgerblue": [30, 144, 255], + "firebrick": [178, 34, 34], + "floralwhite": [255, 250, 240], + "forestgreen": [34, 139, 34], + "fuchsia": [255, 0, 255], + "gainsboro": [220, 220, 220], + "ghostwhite": [248, 248, 255], + "gold": [255, 215, 0], + "goldenrod": [218, 165, 32], + "gray": [128, 128, 128], + "green": [0, 128, 0], + "greenyellow": [173, 255, 47], + "grey": [128, 128, 128], + "honeydew": [240, 255, 240], + "hotpink": [255, 105, 180], + "indianred": [205, 92, 92], + "indigo": [75, 0, 130], + "ivory": [255, 255, 240], + "khaki": [240, 230, 140], + "lavender": [230, 230, 250], + "lavenderblush": [255, 240, 245], + "lawngreen": [124, 252, 0], + "lemonchiffon": [255, 250, 205], + "lightblue": [173, 216, 230], + "lightcoral": [240, 128, 128], + "lightcyan": [224, 255, 255], + "lightgoldenrodyellow": [250, 250, 210], + "lightgray": [211, 211, 211], + "lightgreen": [144, 238, 144], + "lightgrey": [211, 211, 211], + "lightpink": [255, 182, 193], + "lightsalmon": [255, 160, 122], + "lightseagreen": [32, 178, 170], + "lightskyblue": [135, 206, 250], + "lightslategray": [119, 136, 153], + "lightslategrey": [119, 136, 153], + "lightsteelblue": [176, 196, 222], + "lightyellow": [255, 255, 224], + "lime": [0, 255, 0], + "limegreen": [50, 205, 50], + "linen": [250, 240, 230], + "magenta": [255, 0, 255], + "maroon": [128, 0, 0], + "mediumaquamarine": [102, 205, 170], + "mediumblue": [0, 0, 205], + "mediumorchid": [186, 85, 211], + "mediumpurple": [147, 112, 219], + "mediumseagreen": [60, 179, 113], + "mediumslateblue": [123, 104, 238], + "mediumspringgreen": [0, 250, 154], + "mediumturquoise": [72, 209, 204], + "mediumvioletred": [199, 21, 133], + "midnightblue": [25, 25, 112], + "mintcream": [245, 255, 250], + "mistyrose": [255, 228, 225], + "moccasin": [255, 228, 181], + "navajowhite": [255, 222, 173], + "navy": [0, 0, 128], + "oldlace": [253, 245, 230], + "olive": [128, 128, 0], + "olivedrab": [107, 142, 35], + "orange": [255, 165, 0], + "orangered": [255, 69, 0], + "orchid": [218, 112, 214], + "palegoldenrod": [238, 232, 170], + "palegreen": [152, 251, 152], + "paleturquoise": [175, 238, 238], + "palevioletred": [219, 112, 147], + "papayawhip": [255, 239, 213], + "peachpuff": [255, 218, 185], + "peru": [205, 133, 63], + "pink": [255, 192, 203], + "plum": [221, 160, 221], + "powderblue": [176, 224, 230], + "purple": [128, 0, 128], + "rebeccapurple": [102, 51, 153], + "red": [255, 0, 0], + "rosybrown": [188, 143, 143], + "royalblue": [65, 105, 225], + "saddlebrown": [139, 69, 19], + "salmon": [250, 128, 114], + "sandybrown": [244, 164, 96], + "seagreen": [46, 139, 87], + "seashell": [255, 245, 238], + "sienna": [160, 82, 45], + "silver": [192, 192, 192], + "skyblue": [135, 206, 235], + "slateblue": [106, 90, 205], + "slategray": [112, 128, 144], + "slategrey": [112, 128, 144], + "snow": [255, 250, 250], + "springgreen": [0, 255, 127], + "steelblue": [70, 130, 180], + "tan": [210, 180, 140], + "teal": [0, 128, 128], + "thistle": [216, 191, 216], + "tomato": [255, 99, 71], + "turquoise": [64, 224, 208], + "violet": [238, 130, 238], + "wheat": [245, 222, 179], + "white": [255, 255, 255], + "whitesmoke": [245, 245, 245], + "yellow": [255, 255, 0], + "yellowgreen": [154, 205, 50] +}; + + +/***/ }), +/* 388 */ +/***/ (function(module, exports, __webpack_require__) { + +var conversions = __webpack_require__(386); + +/* + this function routes a model to all other models. + + 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). + + conversions that are not possible simply are not included. +*/ + +function buildGraph() { + var graph = {}; + // https://jsperf.com/object-keys-vs-for-in-with-closure/3 + var models = Object.keys(conversions); + + for (var 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; +} + +// https://en.wikipedia.org/wiki/Breadth-first_search +function deriveBFS(fromModel) { + var graph = buildGraph(); + var queue = [fromModel]; // unshift -> queue -> pop + + graph[fromModel].distance = 0; + + while (queue.length) { + var current = queue.pop(); + var adjacents = Object.keys(conversions[current]); + + for (var len = adjacents.length, i = 0; i < len; i++) { + var adjacent = adjacents[i]; + var node = graph[adjacent]; + + if (node.distance === -1) { + node.distance = graph[current].distance + 1; + node.parent = current; + queue.unshift(adjacent); + } + } + } + + return graph; +} + +function link(from, to) { + return function (args) { + return to(from(args)); + }; +} + +function wrapConversion(toModel, graph) { + var path = [graph[toModel].parent, toModel]; + var fn = conversions[graph[toModel].parent][toModel]; + + var 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; + } + + fn.conversion = path; + return fn; +} + +module.exports = function (fromModel) { + var graph = deriveBFS(fromModel); + var conversion = {}; + + var models = Object.keys(graph); + for (var len = models.length, i = 0; i < len; i++) { + var toModel = models[i]; + var node = graph[toModel]; + + if (node.parent === null) { + // no possible conversion, or this node is the source model. + continue; + } + + conversion[toModel] = wrapConversion(toModel, graph); + } + + return conversion; +}; + + + +/***/ }), +/* 389 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const os = __webpack_require__(121); +const hasFlag = __webpack_require__(186); + +const env = process.env; + +let forceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false')) { + forceColor = false; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + forceColor = true; +} +if ('FORCE_COLOR' in env) { + forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0; +} + +function translateLevel(level) { + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +} + +function supportsColor(stream) { + if (forceColor === false) { + return 0; + } + + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } + + if (stream && !stream.isTTY && forceColor !== true) { + return 0; + } + + const min = forceColor ? 1 : 0; + + if (process.platform === 'win32') { + // Node.js 7.5.0 is the first version of Node.js to include a patch to + // libuv that enables 256 color output on Windows. Anything earlier and it + // won't work. However, here we target Node.js 8 at minimum as it is an LTS + // release, and Node.js 7 is not. 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(process.versions.node.split('.')[0]) >= 8 && + 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; + } + + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + + if (env.COLORTERM === 'truecolor') { + return 3; + } + + if ('TERM_PROGRAM' in env) { + const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + 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; + } + + if (env.TERM === 'dumb') { + return min; + } + + return min; +} + +function getSupportLevel(stream) { + const level = supportsColor(stream); + return translateLevel(level); +} + +module.exports = { + supportsColor: getSupportLevel, + stdout: getSupportLevel(process.stdout), + stderr: getSupportLevel(process.stderr) +}; + + +/***/ }), +/* 390 */ +/***/ (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(''); +}; + + +/***/ }), +/* 391 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const ansiRegex = __webpack_require__(392); + +module.exports = string => typeof string === 'string' ? string.replace(ansiRegex(), '') : string; + + +/***/ }), +/* 392 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +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('|'); + + return new RegExp(pattern, onlyFirst ? undefined : 'g'); +}; + + +/***/ }), +/* 393 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var defaults = __webpack_require__(394) +var combining = __webpack_require__(396) + +var DEFAULTS = { + nul: 0, + control: 0 +} + +module.exports = function wcwidth(str) { + return wcswidth(str, DEFAULTS) +} + +module.exports.config = function(opts) { + opts = defaults(opts || {}, DEFAULTS) + return function wcwidth(str) { + return wcswidth(str, opts) + } +} + +/* + * 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. +*/ + +function wcswidth(str, opts) { + if (typeof str !== 'string') return wcwidth(str, opts) + + 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 + } + + return s +} + +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 + + // binary search in table of non-spacing characters + if (bisearch(ucs)) return 0 + + // 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))); +} + +function bisearch(ucs) { + var min = 0 + var max = combining.length - 1 + var mid + + if (ucs < combining[0][0] || ucs > combining[max][1]) return false + + 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 false +} + + +/***/ }), +/* 394 */ +/***/ (function(module, exports, __webpack_require__) { + +var clone = __webpack_require__(395); + +module.exports = function(options, defaults) { + options = options || {}; + + Object.keys(defaults).forEach(function(key) { + if (typeof options[key] === 'undefined') { + options[key] = clone(defaults[key]); + } + }); + + return options; +}; + +/***/ }), +/* 395 */ +/***/ (function(module, exports, __webpack_require__) { + +var clone = (function() { +'use strict'; + +/** + * 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; + } + } + + if (circular) { + var index = allParents.indexOf(parent); + + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } + + for (var i in parent) { + var attrs; + if (proto) { + attrs = Object.getOwnPropertyDescriptor(proto, i); + } + + if (attrs && attrs.set == null) { + continue; + } + child[i] = _clone(parent[i], depth - 1); + } + + return child; + } + + return _clone(parent, depth); +} + +/** + * 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(); +}; + +// private utility functions + +function __objToStr(o) { + return Object.prototype.toString.call(o); +}; +clone.__objToStr = __objToStr; + +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; +} + + +/***/ }), +/* 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"; + + +module.exports = ({stream = process.stdout} = {}) => { + return Boolean( + stream && stream.isTTY && + process.env.TERM !== 'dumb' && + !('CI' in process.env) + ); +}; + + +/***/ }), +/* 398 */ +/***/ (function(module, exports, __webpack_require__) { + +var Stream = __webpack_require__(138) + +module.exports = MuteStream + +// 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 + + // 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 +} + +MuteStream.prototype = Object.create(Stream.prototype) + +Object.defineProperty(MuteStream.prototype, 'constructor', { + value: MuteStream, + enumerable: false +}) + +MuteStream.prototype.mute = function () { + this.muted = true +} + +MuteStream.prototype.unmute = function () { + this.muted = false +} + +Object.defineProperty(MuteStream.prototype, '_onpipe', { + value: onPipe, + enumerable: false, + writable: true, + configurable: true +}) + +function onPipe (src) { + this._src = src +} + +Object.defineProperty(MuteStream.prototype, 'isTTY', { + get: getIsTTY, + set: setIsTTY, + enumerable: true, + configurable: true +}) + +function getIsTTY () { + return( (this._dest) ? this._dest.isTTY + : (this._src) ? this._src.isTTY + : false + ) +} + +// 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 + }) +} + +Object.defineProperty(MuteStream.prototype, 'rows', { + get: function () { + return( this._dest ? this._dest.rows + : this._src ? this._src.rows + : undefined ) + }, enumerable: true, configurable: true }) + +Object.defineProperty(MuteStream.prototype, 'columns', { + get: function () { + return( this._dest ? this._dest.columns + : this._src ? this._src.columns + : undefined ) + }, enumerable: true, configurable: true }) + + +MuteStream.prototype.pipe = function (dest, options) { + this._dest = dest + return Stream.prototype.pipe.call(this, dest, options) +} + +MuteStream.prototype.pause = function () { + if (this._src) return this._src.pause() +} + +MuteStream.prototype.resume = function () { + if (this._src) return this._src.resume() +} + +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) +} + +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') +} + +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) +}} + +MuteStream.prototype.destroy = proxy('destroy') +MuteStream.prototype.destroySoon = proxy('destroySoon') +MuteStream.prototype.close = proxy('close') + + +/***/ }), +/* 399 */ +/***/ (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__(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. + */ + + + + +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`); + } + }); + } + +}; + +/***/ }), +/* 400 */ +/***/ (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__(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. + */ + + + + + + +/** + * 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}).`); + }); + } + +}; + +/***/ }), +/* 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__(402); +/* + * 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. + */ + + +/** + * Number of milliseconds we wait before we fall back to the default watch handler. + */ + +const defaultHandlerDelay = 3000; +/** + * If default watch handler is used, then it's the number of milliseconds we wait for + * any build output before we consider watch task ready. + */ + +const defaultHandlerReadinessTimeout = 2000; +/** + * Describes configurable watch options. + */ + +function getWatchHandlers(buildOutput$, { + handlerDelay = defaultHandlerDelay, + handlerReadinessTimeout = defaultHandlerReadinessTimeout +}) { + const typescriptHandler = buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('$ tsc')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["map"])(() => buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('Compilation complete.')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["mapTo"])('tsc')))); + const webpackHandler = buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('$ webpack')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["map"])(() => buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["first"])(data => data.includes('Chunk Names')), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["mapTo"])('webpack')))); + const defaultHandler = rxjs__WEBPACK_IMPORTED_MODULE_0__["of"](undefined).pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["delay"])(handlerReadinessTimeout), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["map"])(() => buildOutput$.pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["timeout"])(handlerDelay), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["catchError"])(() => rxjs__WEBPACK_IMPORTED_MODULE_0__["of"]('timeout'))))); + return [typescriptHandler, webpackHandler, defaultHandler]; +} + +function waitUntilWatchIsReady(stream, opts = {}) { + const buildOutput$ = new rxjs__WEBPACK_IMPORTED_MODULE_0__["Subject"](); + + const onDataListener = data => buildOutput$.next(data.toString('utf-8')); + + const onEndListener = () => buildOutput$.complete(); + + const onErrorListener = e => buildOutput$.error(e); + + stream.once('end', onEndListener); + stream.once('error', onErrorListener); + stream.on('data', onDataListener); + return rxjs__WEBPACK_IMPORTED_MODULE_0__["race"](getWatchHandlers(buildOutput$, opts)).pipe(Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["mergeMap"])(whenReady => whenReady), Object(rxjs_operators__WEBPACK_IMPORTED_MODULE_1__["finalize"])(() => { + stream.removeListener('data', onDataListener); + stream.removeListener('end', onEndListener); + stream.removeListener('error', onErrorListener); + buildOutput$.complete(); + })).toPromise(); +} + +/***/ }), +/* 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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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); +/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeAll", function() { return _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__["mergeAll"]; }); + +/* 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__["flatMap"]; }); + +/* 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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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__(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 */ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +//# sourceMappingURL=index.js.map + + +/***/ }), +/* 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 _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + + +function audit(durationSelector) { + return function auditOperatorFunction(source) { + return source.lift(new AuditOperator(durationSelector)); + }; +} +var AuditOperator = /*@__PURE__*/ (function () { + function AuditOperator(durationSelector) { + this.durationSelector = durationSelector; + } + AuditOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new AuditSubscriber(subscriber, this.durationSelector)); + }; + return AuditOperator; +}()); +var AuditSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](AuditSubscriber, _super); + function AuditSubscriber(destination, durationSelector) { + var _this = _super.call(this, destination) || this; + _this.durationSelector = durationSelector; + _this.hasValue = false; + return _this; + } + AuditSubscriber.prototype._next = function (value) { + this.value = value; + this.hasValue = true; + if (!this.throttled) { + var duration = void 0; + try { + var durationSelector = this.durationSelector; + duration = durationSelector(value); + } + catch (err) { + return this.destination.error(err); + } + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(duration, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this)); + if (!innerSubscription || innerSubscription.closed) { + this.clearThrottle(); + } + else { + this.add(this.throttled = innerSubscription); + } + } + }; + AuditSubscriber.prototype.clearThrottle = function () { + var _a = this, value = _a.value, hasValue = _a.hasValue, throttled = _a.throttled; + if (throttled) { + this.remove(throttled); + this.throttled = undefined; + throttled.unsubscribe(); + } + if (hasValue) { + this.value = undefined; + this.hasValue = false; + this.destination.next(value); + } + }; + AuditSubscriber.prototype.notifyNext = function () { + this.clearThrottle(); + }; + AuditSubscriber.prototype.notifyComplete = function () { + this.clearThrottle(); + }; + return AuditSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); +//# sourceMappingURL=audit.js.map + + +/***/ }), +/* 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__(403); +/* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(108); +/** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ + + + +function auditTime(duration, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; + } + return Object(_audit__WEBPACK_IMPORTED_MODULE_1__["audit"])(function () { return Object(_observable_timer__WEBPACK_IMPORTED_MODULE_2__["timer"])(duration, scheduler); }); +} +//# sourceMappingURL=auditTime.js.map + + +/***/ }), +/* 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 _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + + +function buffer(closingNotifier) { + return function bufferOperatorFunction(source) { + return source.lift(new BufferOperator(closingNotifier)); + }; +} +var BufferOperator = /*@__PURE__*/ (function () { + function BufferOperator(closingNotifier) { + this.closingNotifier = closingNotifier; + } + BufferOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new BufferSubscriber(subscriber, this.closingNotifier)); + }; + return BufferOperator; +}()); +var BufferSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferSubscriber, _super); + function BufferSubscriber(destination, closingNotifier) { + var _this = _super.call(this, destination) || this; + _this.buffer = []; + _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 () { + var buffer = this.buffer; + this.buffer = []; + this.destination.next(buffer); + }; + return BufferSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); +//# sourceMappingURL=buffer.js.map + + +/***/ }), +/* 406 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return bufferCount; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function bufferCount(bufferSize, startBufferEvery) { + if (startBufferEvery === void 0) { + startBufferEvery = null; + } + return function bufferCountOperatorFunction(source) { + return source.lift(new BufferCountOperator(bufferSize, startBufferEvery)); + }; +} +var BufferCountOperator = /*@__PURE__*/ (function () { + function BufferCountOperator(bufferSize, startBufferEvery) { + this.bufferSize = bufferSize; + this.startBufferEvery = startBufferEvery; + if (!startBufferEvery || bufferSize === startBufferEvery) { + this.subscriberClass = BufferCountSubscriber; + } + else { + this.subscriberClass = BufferSkipCountSubscriber; + } + } + BufferCountOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new this.subscriberClass(subscriber, this.bufferSize, this.startBufferEvery)); + }; + return BufferCountOperator; +}()); +var BufferCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferCountSubscriber, _super); + function BufferCountSubscriber(destination, bufferSize) { + var _this = _super.call(this, destination) || this; + _this.bufferSize = bufferSize; + _this.buffer = []; + return _this; + } + BufferCountSubscriber.prototype._next = function (value) { + var buffer = this.buffer; + buffer.push(value); + if (buffer.length == this.bufferSize) { + this.destination.next(buffer); + this.buffer = []; + } + }; + BufferCountSubscriber.prototype._complete = function () { + var buffer = this.buffer; + if (buffer.length > 0) { + this.destination.next(buffer); + } + _super.prototype._complete.call(this); + }; + return BufferCountSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +var BufferSkipCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferSkipCountSubscriber, _super); + function BufferSkipCountSubscriber(destination, bufferSize, startBufferEvery) { + var _this = _super.call(this, destination) || this; + _this.bufferSize = bufferSize; + _this.startBufferEvery = startBufferEvery; + _this.buffers = []; + _this.count = 0; + return _this; + } + BufferSkipCountSubscriber.prototype._next = function (value) { + var _a = this, bufferSize = _a.bufferSize, startBufferEvery = _a.startBufferEvery, buffers = _a.buffers, count = _a.count; + this.count++; + if (count % startBufferEvery === 0) { + buffers.push([]); + } + for (var i = buffers.length; i--;) { + var buffer = buffers[i]; + buffer.push(value); + if (buffer.length === bufferSize) { + buffers.splice(i, 1); + this.destination.next(buffer); + } + } + }; + BufferSkipCountSubscriber.prototype._complete = function () { + var _a = this, buffers = _a.buffers, destination = _a.destination; + while (buffers.length > 0) { + var buffer = buffers.shift(); + if (buffer.length > 0) { + destination.next(buffer); + } + } + _super.prototype._complete.call(this); + }; + return BufferSkipCountSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=bufferCount.js.map + + +/***/ }), +/* 407 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return bufferTime; }); +/* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(45); +/** PURE_IMPORTS_START tslib,_scheduler_async,_Subscriber,_util_isScheduler PURE_IMPORTS_END */ + + + + +function bufferTime(bufferTimeSpan) { + var length = arguments.length; + var scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_3__["isScheduler"])(arguments[arguments.length - 1])) { + scheduler = arguments[arguments.length - 1]; + length--; + } + var bufferCreationInterval = null; + if (length >= 2) { + bufferCreationInterval = arguments[1]; + } + var maxBufferSize = Number.POSITIVE_INFINITY; + if (length >= 3) { + maxBufferSize = arguments[2]; + } + return function bufferTimeOperatorFunction(source) { + return source.lift(new BufferTimeOperator(bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler)); + }; +} +var BufferTimeOperator = /*@__PURE__*/ (function () { + function BufferTimeOperator(bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler) { + this.bufferTimeSpan = bufferTimeSpan; + this.bufferCreationInterval = bufferCreationInterval; + this.maxBufferSize = maxBufferSize; + this.scheduler = scheduler; + } + BufferTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new BufferTimeSubscriber(subscriber, this.bufferTimeSpan, this.bufferCreationInterval, this.maxBufferSize, this.scheduler)); + }; + return BufferTimeOperator; +}()); +var Context = /*@__PURE__*/ (function () { + function Context() { + this.buffer = []; + } + return Context; +}()); +var BufferTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferTimeSubscriber, _super); + function BufferTimeSubscriber(destination, bufferTimeSpan, bufferCreationInterval, maxBufferSize, scheduler) { + var _this = _super.call(this, destination) || this; + _this.bufferTimeSpan = bufferTimeSpan; + _this.bufferCreationInterval = bufferCreationInterval; + _this.maxBufferSize = maxBufferSize; + _this.scheduler = scheduler; + _this.contexts = []; + var context = _this.openContext(); + _this.timespanOnly = bufferCreationInterval == null || bufferCreationInterval < 0; + if (_this.timespanOnly) { + var timeSpanOnlyState = { subscriber: _this, context: context, bufferTimeSpan: bufferTimeSpan }; + _this.add(context.closeAction = scheduler.schedule(dispatchBufferTimeSpanOnly, bufferTimeSpan, timeSpanOnlyState)); + } + else { + var closeState = { subscriber: _this, context: context }; + var creationState = { bufferTimeSpan: bufferTimeSpan, bufferCreationInterval: bufferCreationInterval, subscriber: _this, scheduler: scheduler }; + _this.add(context.closeAction = scheduler.schedule(dispatchBufferClose, bufferTimeSpan, closeState)); + _this.add(scheduler.schedule(dispatchBufferCreation, bufferCreationInterval, creationState)); + } + return _this; + } + BufferTimeSubscriber.prototype._next = function (value) { + var contexts = this.contexts; + var len = contexts.length; + var filledBufferContext; + for (var i = 0; i < len; i++) { + var context_1 = contexts[i]; + var buffer = context_1.buffer; + buffer.push(value); + if (buffer.length == this.maxBufferSize) { + filledBufferContext = context_1; + } + } + if (filledBufferContext) { + this.onBufferFull(filledBufferContext); + } + }; + BufferTimeSubscriber.prototype._error = function (err) { + this.contexts.length = 0; + _super.prototype._error.call(this, err); + }; + BufferTimeSubscriber.prototype._complete = function () { + var _a = this, contexts = _a.contexts, destination = _a.destination; + while (contexts.length > 0) { + var context_2 = contexts.shift(); + destination.next(context_2.buffer); + } + _super.prototype._complete.call(this); + }; + BufferTimeSubscriber.prototype._unsubscribe = function () { + this.contexts = null; + }; + BufferTimeSubscriber.prototype.onBufferFull = function (context) { + this.closeContext(context); + var closeAction = context.closeAction; + closeAction.unsubscribe(); + this.remove(closeAction); + if (!this.closed && this.timespanOnly) { + context = this.openContext(); + var bufferTimeSpan = this.bufferTimeSpan; + var timeSpanOnlyState = { subscriber: this, context: context, bufferTimeSpan: bufferTimeSpan }; + this.add(context.closeAction = this.scheduler.schedule(dispatchBufferTimeSpanOnly, bufferTimeSpan, timeSpanOnlyState)); + } + }; + BufferTimeSubscriber.prototype.openContext = function () { + var context = new Context(); + this.contexts.push(context); + return context; + }; + BufferTimeSubscriber.prototype.closeContext = function (context) { + this.destination.next(context.buffer); + var contexts = this.contexts; + var spliceIndex = contexts ? contexts.indexOf(context) : -1; + if (spliceIndex >= 0) { + contexts.splice(contexts.indexOf(context), 1); + } + }; + return BufferTimeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); +function dispatchBufferTimeSpanOnly(state) { + var subscriber = state.subscriber; + var prevContext = state.context; + if (prevContext) { + subscriber.closeContext(prevContext); + } + if (!subscriber.closed) { + state.context = subscriber.openContext(); + state.context.closeAction = this.schedule(state, state.bufferTimeSpan); + } +} +function dispatchBufferCreation(state) { + var bufferCreationInterval = state.bufferCreationInterval, bufferTimeSpan = state.bufferTimeSpan, subscriber = state.subscriber, scheduler = state.scheduler; + var context = subscriber.openContext(); + var action = this; + if (!subscriber.closed) { + subscriber.add(context.closeAction = scheduler.schedule(dispatchBufferClose, bufferTimeSpan, { subscriber: subscriber, context: context })); + action.schedule(state, bufferCreationInterval); + } +} +function dispatchBufferClose(arg) { + var subscriber = arg.subscriber, context = arg.context; + subscriber.closeContext(context); +} +//# sourceMappingURL=bufferTime.js.map + + +/***/ }), +/* 408 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return bufferToggle; }); +/* 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 _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70); +/* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69); +/** PURE_IMPORTS_START tslib,_Subscription,_util_subscribeToResult,_OuterSubscriber PURE_IMPORTS_END */ + + + + +function bufferToggle(openings, closingSelector) { + return function bufferToggleOperatorFunction(source) { + return source.lift(new BufferToggleOperator(openings, closingSelector)); + }; +} +var BufferToggleOperator = /*@__PURE__*/ (function () { + function BufferToggleOperator(openings, closingSelector) { + this.openings = openings; + this.closingSelector = closingSelector; + } + BufferToggleOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new BufferToggleSubscriber(subscriber, this.openings, this.closingSelector)); + }; + return BufferToggleOperator; +}()); +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.closingSelector = closingSelector; + _this.contexts = []; + _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, openings)); + return _this; + } + BufferToggleSubscriber.prototype._next = function (value) { + var contexts = this.contexts; + var len = contexts.length; + for (var i = 0; i < len; i++) { + contexts[i].buffer.push(value); + } + }; + BufferToggleSubscriber.prototype._error = function (err) { + var contexts = this.contexts; + while (contexts.length > 0) { + var context_1 = contexts.shift(); + context_1.subscription.unsubscribe(); + context_1.buffer = null; + context_1.subscription = null; + } + this.contexts = null; + _super.prototype._error.call(this, err); + }; + BufferToggleSubscriber.prototype._complete = function () { + var contexts = this.contexts; + while (contexts.length > 0) { + var context_2 = contexts.shift(); + this.destination.next(context_2.buffer); + context_2.subscription.unsubscribe(); + context_2.buffer = null; + context_2.subscription = null; + } + this.contexts = null; + _super.prototype._complete.call(this); + }; + BufferToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue) { + outerValue ? this.closeBuffer(outerValue) : this.openBuffer(innerValue); + }; + BufferToggleSubscriber.prototype.notifyComplete = function (innerSub) { + this.closeBuffer(innerSub.context); + }; + BufferToggleSubscriber.prototype.openBuffer = function (value) { + try { + var closingSelector = this.closingSelector; + var closingNotifier = closingSelector.call(this, value); + if (closingNotifier) { + this.trySubscribe(closingNotifier); + } + } + catch (err) { + this._error(err); + } + }; + BufferToggleSubscriber.prototype.closeBuffer = function (context) { + var contexts = this.contexts; + if (contexts && context) { + var buffer = context.buffer, subscription = context.subscription; + this.destination.next(buffer); + contexts.splice(contexts.indexOf(context), 1); + this.remove(subscription); + subscription.unsubscribe(); + } + }; + BufferToggleSubscriber.prototype.trySubscribe = function (closingNotifier) { + var contexts = this.contexts; + var buffer = []; + var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); + var context = { buffer: buffer, subscription: subscription }; + contexts.push(context); + var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, closingNotifier, context); + if (!innerSubscription || innerSubscription.closed) { + this.closeBuffer(context); + } + else { + innerSubscription.context = context; + this.add(innerSubscription); + subscription.add(innerSubscription); + } + }; + return BufferToggleSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); +//# sourceMappingURL=bufferToggle.js.map + + +/***/ }), +/* 409 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__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 _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_Subscription,_innerSubscribe PURE_IMPORTS_END */ + + + +function bufferWhen(closingSelector) { + return function (source) { + return source.lift(new BufferWhenOperator(closingSelector)); + }; +} +var BufferWhenOperator = /*@__PURE__*/ (function () { + function BufferWhenOperator(closingSelector) { + this.closingSelector = closingSelector; + } + BufferWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new BufferWhenSubscriber(subscriber, this.closingSelector)); + }; + return BufferWhenOperator; +}()); +var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](BufferWhenSubscriber, _super); + function BufferWhenSubscriber(destination, closingSelector) { + var _this = _super.call(this, destination) || this; + _this.closingSelector = closingSelector; + _this.subscribing = false; + _this.openBuffer(); + return _this; + } + BufferWhenSubscriber.prototype._next = function (value) { + this.buffer.push(value); + }; + BufferWhenSubscriber.prototype._complete = function () { + var buffer = this.buffer; + if (buffer) { + this.destination.next(buffer); + } + _super.prototype._complete.call(this); + }; + BufferWhenSubscriber.prototype._unsubscribe = function () { + this.buffer = undefined; + this.subscribing = false; + }; + BufferWhenSubscriber.prototype.notifyNext = function () { + this.openBuffer(); + }; + BufferWhenSubscriber.prototype.notifyComplete = function () { + if (this.subscribing) { + this.complete(); + } + else { + this.openBuffer(); + } + }; + BufferWhenSubscriber.prototype.openBuffer = function () { + var closingSubscription = this.closingSubscription; + if (closingSubscription) { + this.remove(closingSubscription); + closingSubscription.unsubscribe(); + } + var buffer = this.buffer; + if (this.buffer) { + this.destination.next(buffer); + } + this.buffer = []; + var closingNotifier; + try { + var closingSelector = this.closingSelector; + closingNotifier = closingSelector(); + } + catch (err) { + return this.error(err); + } + closingSubscription = new _Subscription__WEBPACK_IMPORTED_MODULE_1__["Subscription"](); + this.closingSubscription = closingSubscription; + this.add(closingSubscription); + this.subscribing = true; + closingSubscription.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["innerSubscribe"])(closingNotifier, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleInnerSubscriber"](this))); + this.subscribing = false; + }; + return BufferWhenSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleOuterSubscriber"])); +//# sourceMappingURL=bufferWhen.js.map + + +/***/ }), +/* 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 _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + + +function catchError(selector) { + return function catchErrorOperatorFunction(source) { + var operator = new CatchOperator(selector); + var caught = source.lift(operator); + return (operator.caught = caught); + }; +} +var CatchOperator = /*@__PURE__*/ (function () { + function CatchOperator(selector) { + this.selector = selector; + } + CatchOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new CatchSubscriber(subscriber, this.selector, this.caught)); + }; + return CatchOperator; +}()); +var CatchSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CatchSubscriber, _super); + function CatchSubscriber(destination, selector, caught) { + var _this = _super.call(this, destination) || this; + _this.selector = selector; + _this.caught = caught; + return _this; + } + CatchSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var result = void 0; + try { + result = this.selector(err, this.caught); + } + catch (err2) { + _super.prototype.error.call(this, err2); + return; + } + this._unsubscribeAndRecycle(); + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this); + this.add(innerSubscriber); + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(result, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + this.add(innerSubscription); + } + } + }; + return CatchSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); +//# sourceMappingURL=catchError.js.map + + +/***/ }), +/* 411 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return combineAll; }); +/* harmony import */ var _observable_combineLatest__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(68); +/** PURE_IMPORTS_START _observable_combineLatest PURE_IMPORTS_END */ + +function combineAll(project) { + return function (source) { return source.lift(new _observable_combineLatest__WEBPACK_IMPORTED_MODULE_0__["CombineLatestOperator"](project)); }; +} +//# sourceMappingURL=combineAll.js.map + + +/***/ }), +/* 412 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return combineLatest; }); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18); +/* harmony import */ var _observable_combineLatest__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68); +/* harmony import */ var _observable_from__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(83); +/** PURE_IMPORTS_START _util_isArray,_observable_combineLatest,_observable_from PURE_IMPORTS_END */ + + + +var none = {}; +function combineLatest() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + var project = null; + if (typeof observables[observables.length - 1] === 'function') { + project = observables.pop(); + } + if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(observables[0])) { + observables = observables[0].slice(); + } + return function (source) { return source.lift.call(Object(_observable_from__WEBPACK_IMPORTED_MODULE_2__["from"])([source].concat(observables)), new _observable_combineLatest__WEBPACK_IMPORTED_MODULE_1__["CombineLatestOperator"](project)); }; +} +//# sourceMappingURL=combineLatest.js.map + + +/***/ }), +/* 413 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return concat; }); +/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(79); +/** PURE_IMPORTS_START _observable_concat PURE_IMPORTS_END */ + +function concat() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + return function (source) { return source.lift.call(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"].apply(void 0, [source].concat(observables))); }; +} +//# sourceMappingURL=concat.js.map + + +/***/ }), +/* 414 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return concatMap; }); +/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82); +/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ + +function concatMap(project, resultSelector) { + return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(project, resultSelector, 1); +} +//# sourceMappingURL=concatMap.js.map + + +/***/ }), +/* 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__(414); +/** PURE_IMPORTS_START _concatMap PURE_IMPORTS_END */ + +function concatMapTo(innerObservable, resultSelector) { + return Object(_concatMap__WEBPACK_IMPORTED_MODULE_0__["concatMap"])(function () { return innerObservable; }, resultSelector); +} +//# sourceMappingURL=concatMapTo.js.map + + +/***/ }), +/* 416 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "count", function() { return count; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function count(predicate) { + return function (source) { return source.lift(new CountOperator(predicate, source)); }; +} +var CountOperator = /*@__PURE__*/ (function () { + function CountOperator(predicate, source) { + this.predicate = predicate; + this.source = source; + } + CountOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new CountSubscriber(subscriber, this.predicate, this.source)); + }; + return CountOperator; +}()); +var CountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CountSubscriber, _super); + function CountSubscriber(destination, predicate, source) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.source = source; + _this.count = 0; + _this.index = 0; + return _this; + } + CountSubscriber.prototype._next = function (value) { + if (this.predicate) { + this._tryPredicate(value); + } + else { + this.count++; + } + }; + CountSubscriber.prototype._tryPredicate = function (value) { + var result; + try { + result = this.predicate(value, this.index++, this.source); + } + catch (err) { + this.destination.error(err); + return; + } + if (result) { + this.count++; + } + }; + CountSubscriber.prototype._complete = function () { + this.destination.next(this.count); + this.destination.complete(); + }; + return CountSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=count.js.map + + +/***/ }), +/* 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 _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + + +function debounce(durationSelector) { + return function (source) { return source.lift(new DebounceOperator(durationSelector)); }; +} +var DebounceOperator = /*@__PURE__*/ (function () { + function DebounceOperator(durationSelector) { + this.durationSelector = durationSelector; + } + DebounceOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DebounceSubscriber(subscriber, this.durationSelector)); + }; + return DebounceOperator; +}()); +var DebounceSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DebounceSubscriber, _super); + function DebounceSubscriber(destination, durationSelector) { + var _this = _super.call(this, destination) || this; + _this.durationSelector = durationSelector; + _this.hasValue = false; + return _this; + } + DebounceSubscriber.prototype._next = function (value) { + try { + var result = this.durationSelector.call(this, value); + if (result) { + this._tryNext(value, result); + } + } + catch (err) { + this.destination.error(err); + } + }; + DebounceSubscriber.prototype._complete = function () { + this.emitValue(); + this.destination.complete(); + }; + DebounceSubscriber.prototype._tryNext = function (value, duration) { + var subscription = this.durationSubscription; + this.value = value; + this.hasValue = true; + if (subscription) { + subscription.unsubscribe(); + this.remove(subscription); + } + 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 () { + this.emitValue(); + }; + DebounceSubscriber.prototype.notifyComplete = function () { + this.emitValue(); + }; + DebounceSubscriber.prototype.emitValue = function () { + if (this.hasValue) { + var value = this.value; + var subscription = this.durationSubscription; + if (subscription) { + this.durationSubscription = undefined; + subscription.unsubscribe(); + this.remove(subscription); + } + this.value = undefined; + this.hasValue = false; + _super.prototype._next.call(this, value); + } + }; + return DebounceSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); +//# sourceMappingURL=debounce.js.map + + +/***/ }), +/* 418 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return debounceTime; }); +/* 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); +/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async PURE_IMPORTS_END */ + + + +function debounceTime(dueTime, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; + } + return function (source) { return source.lift(new DebounceTimeOperator(dueTime, scheduler)); }; +} +var DebounceTimeOperator = /*@__PURE__*/ (function () { + function DebounceTimeOperator(dueTime, scheduler) { + this.dueTime = dueTime; + this.scheduler = scheduler; + } + DebounceTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DebounceTimeSubscriber(subscriber, this.dueTime, this.scheduler)); + }; + return DebounceTimeOperator; +}()); +var DebounceTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DebounceTimeSubscriber, _super); + function DebounceTimeSubscriber(destination, dueTime, scheduler) { + var _this = _super.call(this, destination) || this; + _this.dueTime = dueTime; + _this.scheduler = scheduler; + _this.debouncedSubscription = null; + _this.lastValue = null; + _this.hasValue = false; + return _this; + } + DebounceTimeSubscriber.prototype._next = function (value) { + this.clearDebounce(); + this.lastValue = value; + this.hasValue = true; + this.add(this.debouncedSubscription = this.scheduler.schedule(dispatchNext, this.dueTime, this)); + }; + DebounceTimeSubscriber.prototype._complete = function () { + this.debouncedNext(); + this.destination.complete(); + }; + DebounceTimeSubscriber.prototype.debouncedNext = function () { + this.clearDebounce(); + if (this.hasValue) { + var lastValue = this.lastValue; + this.lastValue = null; + this.hasValue = false; + this.destination.next(lastValue); + } + }; + DebounceTimeSubscriber.prototype.clearDebounce = function () { + var debouncedSubscription = this.debouncedSubscription; + if (debouncedSubscription !== null) { + this.remove(debouncedSubscription); + debouncedSubscription.unsubscribe(); + this.debouncedSubscription = null; + } + }; + return DebounceTimeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +function dispatchNext(subscriber) { + subscriber.debouncedNext(); +} +//# sourceMappingURL=debounceTime.js.map + + +/***/ }), +/* 419 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return defaultIfEmpty; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function defaultIfEmpty(defaultValue) { + if (defaultValue === void 0) { + defaultValue = null; + } + return function (source) { return source.lift(new DefaultIfEmptyOperator(defaultValue)); }; +} +var DefaultIfEmptyOperator = /*@__PURE__*/ (function () { + function DefaultIfEmptyOperator(defaultValue) { + this.defaultValue = defaultValue; + } + DefaultIfEmptyOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DefaultIfEmptySubscriber(subscriber, this.defaultValue)); + }; + return DefaultIfEmptyOperator; +}()); +var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DefaultIfEmptySubscriber, _super); + function DefaultIfEmptySubscriber(destination, defaultValue) { + var _this = _super.call(this, destination) || this; + _this.defaultValue = defaultValue; + _this.isEmpty = true; + return _this; + } + DefaultIfEmptySubscriber.prototype._next = function (value) { + this.isEmpty = false; + this.destination.next(value); + }; + DefaultIfEmptySubscriber.prototype._complete = function () { + if (this.isEmpty) { + this.destination.next(this.defaultValue); + } + this.destination.complete(); + }; + return DefaultIfEmptySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=defaultIfEmpty.js.map + + +/***/ }), +/* 420 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__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__(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 */ + + + + + +function delay(delay, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; + } + var absoluteDelay = Object(_util_isDate__WEBPACK_IMPORTED_MODULE_2__["isDate"])(delay); + var delayFor = absoluteDelay ? (+delay - scheduler.now()) : Math.abs(delay); + return function (source) { return source.lift(new DelayOperator(delayFor, scheduler)); }; +} +var DelayOperator = /*@__PURE__*/ (function () { + function DelayOperator(delay, scheduler) { + this.delay = delay; + this.scheduler = scheduler; + } + DelayOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DelaySubscriber(subscriber, this.delay, this.scheduler)); + }; + return DelayOperator; +}()); +var DelaySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DelaySubscriber, _super); + function DelaySubscriber(destination, delay, scheduler) { + var _this = _super.call(this, destination) || this; + _this.delay = delay; + _this.scheduler = scheduler; + _this.queue = []; + _this.active = false; + _this.errored = false; + return _this; + } + DelaySubscriber.dispatch = function (state) { + var source = state.source; + var queue = source.queue; + var scheduler = state.scheduler; + var destination = state.destination; + while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) { + queue.shift().notification.observe(destination); + } + if (queue.length > 0) { + var delay_1 = Math.max(0, queue[0].time - scheduler.now()); + this.schedule(state, delay_1); + } + else { + this.unsubscribe(); + source.active = false; + } + }; + DelaySubscriber.prototype._schedule = function (scheduler) { + this.active = true; + var destination = this.destination; + destination.add(scheduler.schedule(DelaySubscriber.dispatch, this.delay, { + source: this, destination: this.destination, scheduler: scheduler + })); + }; + DelaySubscriber.prototype.scheduleNotification = function (notification) { + if (this.errored === true) { + return; + } + var scheduler = this.scheduler; + var message = new DelayMessage(scheduler.now() + this.delay, notification); + this.queue.push(message); + if (this.active === false) { + this._schedule(scheduler); + } + }; + DelaySubscriber.prototype._next = function (value) { + this.scheduleNotification(_Notification__WEBPACK_IMPORTED_MODULE_4__["Notification"].createNext(value)); + }; + DelaySubscriber.prototype._error = function (err) { + this.errored = true; + this.queue = []; + this.destination.error(err); + this.unsubscribe(); + }; + DelaySubscriber.prototype._complete = function () { + this.scheduleNotification(_Notification__WEBPACK_IMPORTED_MODULE_4__["Notification"].createComplete()); + this.unsubscribe(); + }; + return DelaySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); +var DelayMessage = /*@__PURE__*/ (function () { + function DelayMessage(time, notification) { + this.time = time; + this.notification = notification; + } + return DelayMessage; +}()); +//# sourceMappingURL=delay.js.map + + +/***/ }), +/* 421 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDate", function() { return isDate; }); +/** PURE_IMPORTS_START PURE_IMPORTS_END */ +function isDate(value) { + return value instanceof Date && !isNaN(+value); +} +//# sourceMappingURL=isDate.js.map + + +/***/ }), +/* 422 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return delayWhen; }); +/* 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 _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69); +/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(70); +/** PURE_IMPORTS_START tslib,_Subscriber,_Observable,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ + + + + + +function delayWhen(delayDurationSelector, subscriptionDelay) { + if (subscriptionDelay) { + return function (source) { + return new SubscriptionDelayObservable(source, subscriptionDelay) + .lift(new DelayWhenOperator(delayDurationSelector)); + }; + } + return function (source) { return source.lift(new DelayWhenOperator(delayDurationSelector)); }; +} +var DelayWhenOperator = /*@__PURE__*/ (function () { + function DelayWhenOperator(delayDurationSelector) { + this.delayDurationSelector = delayDurationSelector; + } + DelayWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DelayWhenSubscriber(subscriber, this.delayDurationSelector)); + }; + return DelayWhenOperator; +}()); +var DelayWhenSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DelayWhenSubscriber, _super); + function DelayWhenSubscriber(destination, delayDurationSelector) { + var _this = _super.call(this, destination) || this; + _this.delayDurationSelector = delayDurationSelector; + _this.completed = false; + _this.delayNotifierSubscriptions = []; + _this.index = 0; + return _this; + } + DelayWhenSubscriber.prototype.notifyNext = function (outerValue, _innerValue, _outerIndex, _innerIndex, innerSub) { + this.destination.next(outerValue); + this.removeSubscription(innerSub); + this.tryComplete(); + }; + DelayWhenSubscriber.prototype.notifyError = function (error, innerSub) { + this._error(error); + }; + DelayWhenSubscriber.prototype.notifyComplete = function (innerSub) { + var value = this.removeSubscription(innerSub); + if (value) { + this.destination.next(value); + } + this.tryComplete(); + }; + DelayWhenSubscriber.prototype._next = function (value) { + var index = this.index++; + try { + var delayNotifier = this.delayDurationSelector(value, index); + if (delayNotifier) { + this.tryDelay(delayNotifier, value); + } + } + catch (err) { + this.destination.error(err); + } + }; + DelayWhenSubscriber.prototype._complete = function () { + this.completed = true; + this.tryComplete(); + this.unsubscribe(); + }; + DelayWhenSubscriber.prototype.removeSubscription = function (subscription) { + subscription.unsubscribe(); + var subscriptionIdx = this.delayNotifierSubscriptions.indexOf(subscription); + if (subscriptionIdx !== -1) { + this.delayNotifierSubscriptions.splice(subscriptionIdx, 1); + } + return subscription.outerValue; + }; + DelayWhenSubscriber.prototype.tryDelay = function (delayNotifier, value) { + var notifierSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, delayNotifier, value); + if (notifierSubscription && !notifierSubscription.closed) { + var destination = this.destination; + destination.add(notifierSubscription); + this.delayNotifierSubscriptions.push(notifierSubscription); + } + }; + DelayWhenSubscriber.prototype.tryComplete = function () { + if (this.completed && this.delayNotifierSubscriptions.length === 0) { + this.destination.complete(); + } + }; + return DelayWhenSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); +var SubscriptionDelayObservable = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscriptionDelayObservable, _super); + function SubscriptionDelayObservable(source, subscriptionDelay) { + var _this = _super.call(this) || this; + _this.source = source; + _this.subscriptionDelay = subscriptionDelay; + return _this; + } + SubscriptionDelayObservable.prototype._subscribe = function (subscriber) { + this.subscriptionDelay.subscribe(new SubscriptionDelaySubscriber(subscriber, this.source)); + }; + return SubscriptionDelayObservable; +}(_Observable__WEBPACK_IMPORTED_MODULE_2__["Observable"])); +var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscriptionDelaySubscriber, _super); + function SubscriptionDelaySubscriber(parent, source) { + var _this = _super.call(this) || this; + _this.parent = parent; + _this.source = source; + _this.sourceSubscribed = false; + return _this; + } + SubscriptionDelaySubscriber.prototype._next = function (unused) { + this.subscribeToSource(); + }; + SubscriptionDelaySubscriber.prototype._error = function (err) { + this.unsubscribe(); + this.parent.error(err); + }; + SubscriptionDelaySubscriber.prototype._complete = function () { + this.unsubscribe(); + this.subscribeToSource(); + }; + SubscriptionDelaySubscriber.prototype.subscribeToSource = function () { + if (!this.sourceSubscribed) { + this.sourceSubscribed = true; + this.unsubscribe(); + this.source.subscribe(this.parent); + } + }; + return SubscriptionDelaySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=delayWhen.js.map + + +/***/ }), +/* 423 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return dematerialize; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function dematerialize() { + return function dematerializeOperatorFunction(source) { + return source.lift(new DeMaterializeOperator()); + }; +} +var DeMaterializeOperator = /*@__PURE__*/ (function () { + function DeMaterializeOperator() { + } + DeMaterializeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DeMaterializeSubscriber(subscriber)); + }; + return DeMaterializeOperator; +}()); +var DeMaterializeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DeMaterializeSubscriber, _super); + function DeMaterializeSubscriber(destination) { + return _super.call(this, destination) || this; + } + DeMaterializeSubscriber.prototype._next = function (value) { + value.observe(this.destination); + }; + return DeMaterializeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=dematerialize.js.map + + +/***/ }), +/* 424 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__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 _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + + +function distinct(keySelector, flushes) { + return function (source) { return source.lift(new DistinctOperator(keySelector, flushes)); }; +} +var DistinctOperator = /*@__PURE__*/ (function () { + function DistinctOperator(keySelector, flushes) { + this.keySelector = keySelector; + this.flushes = flushes; + } + DistinctOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DistinctSubscriber(subscriber, this.keySelector, this.flushes)); + }; + return DistinctOperator; +}()); +var DistinctSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DistinctSubscriber, _super); + function DistinctSubscriber(destination, keySelector, flushes) { + var _this = _super.call(this, destination) || this; + _this.keySelector = keySelector; + _this.values = new Set(); + if (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 () { + this.values.clear(); + }; + DistinctSubscriber.prototype.notifyError = function (error) { + this._error(error); + }; + DistinctSubscriber.prototype._next = function (value) { + if (this.keySelector) { + this._useKeySelector(value); + } + else { + this._finalizeNext(value, value); + } + }; + DistinctSubscriber.prototype._useKeySelector = function (value) { + var key; + var destination = this.destination; + try { + key = this.keySelector(value); + } + catch (err) { + destination.error(err); + return; + } + this._finalizeNext(key, value); + }; + DistinctSubscriber.prototype._finalizeNext = function (key, value) { + var values = this.values; + if (!values.has(key)) { + values.add(key); + this.destination.next(value); + } + }; + return DistinctSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); + +//# sourceMappingURL=distinct.js.map + + +/***/ }), +/* 425 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return distinctUntilChanged; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function distinctUntilChanged(compare, keySelector) { + return function (source) { return source.lift(new DistinctUntilChangedOperator(compare, keySelector)); }; +} +var DistinctUntilChangedOperator = /*@__PURE__*/ (function () { + function DistinctUntilChangedOperator(compare, keySelector) { + this.compare = compare; + this.keySelector = keySelector; + } + DistinctUntilChangedOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new DistinctUntilChangedSubscriber(subscriber, this.compare, this.keySelector)); + }; + return DistinctUntilChangedOperator; +}()); +var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DistinctUntilChangedSubscriber, _super); + function DistinctUntilChangedSubscriber(destination, compare, keySelector) { + var _this = _super.call(this, destination) || this; + _this.keySelector = keySelector; + _this.hasKey = false; + if (typeof compare === 'function') { + _this.compare = compare; + } + return _this; + } + DistinctUntilChangedSubscriber.prototype.compare = function (x, y) { + return x === y; + }; + DistinctUntilChangedSubscriber.prototype._next = function (value) { + var key; + try { + var keySelector = this.keySelector; + key = keySelector ? keySelector(value) : value; + } + catch (err) { + return this.destination.error(err); + } + var result = false; + if (this.hasKey) { + try { + var compare = this.compare; + result = compare(this.key, key); + } + catch (err) { + return this.destination.error(err); + } + } + else { + this.hasKey = true; + } + if (!result) { + this.key = key; + this.destination.next(value); + } + }; + return DistinctUntilChangedSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=distinctUntilChanged.js.map + + +/***/ }), +/* 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__(425); +/** PURE_IMPORTS_START _distinctUntilChanged PURE_IMPORTS_END */ + +function distinctUntilKeyChanged(key, compare) { + return Object(_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__["distinctUntilChanged"])(function (x, y) { return compare ? compare(x[key], y[key]) : x[key] === y[key]; }); +} +//# sourceMappingURL=distinctUntilKeyChanged.js.map + + +/***/ }), +/* 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__(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 */ + + + + + +function elementAt(index, defaultValue) { + if (index < 0) { + throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__["ArgumentOutOfRangeError"](); + } + var hasDefaultValue = arguments.length >= 2; + return function (source) { + return source.pipe(Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return i === index; }), Object(_take__WEBPACK_IMPORTED_MODULE_4__["take"])(1), hasDefaultValue + ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__["defaultIfEmpty"])(defaultValue) + : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__["throwIfEmpty"])(function () { return new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__["ArgumentOutOfRangeError"](); })); + }; +} +//# sourceMappingURL=elementAt.js.map + + +/***/ }), +/* 428 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return throwIfEmpty; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(63); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_util_EmptyError,_Subscriber PURE_IMPORTS_END */ + + + +function throwIfEmpty(errorFactory) { + if (errorFactory === void 0) { + errorFactory = defaultErrorFactory; + } + return function (source) { + return source.lift(new ThrowIfEmptyOperator(errorFactory)); + }; +} +var ThrowIfEmptyOperator = /*@__PURE__*/ (function () { + function ThrowIfEmptyOperator(errorFactory) { + this.errorFactory = errorFactory; + } + ThrowIfEmptyOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ThrowIfEmptySubscriber(subscriber, this.errorFactory)); + }; + return ThrowIfEmptyOperator; +}()); +var ThrowIfEmptySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrowIfEmptySubscriber, _super); + function ThrowIfEmptySubscriber(destination, errorFactory) { + var _this = _super.call(this, destination) || this; + _this.errorFactory = errorFactory; + _this.hasValue = false; + return _this; + } + ThrowIfEmptySubscriber.prototype._next = function (value) { + this.hasValue = true; + this.destination.next(value); + }; + ThrowIfEmptySubscriber.prototype._complete = function () { + if (!this.hasValue) { + var err = void 0; + try { + err = this.errorFactory(); + } + catch (e) { + err = e; + } + this.destination.error(err); + } + else { + return this.destination.complete(); + } + }; + return ThrowIfEmptySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); +function defaultErrorFactory() { + return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__["EmptyError"](); +} +//# sourceMappingURL=throwIfEmpty.js.map + + +/***/ }), +/* 429 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "take", function() { return take; }); +/* 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 _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(62); +/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(43); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ + + + + +function take(count) { + return function (source) { + if (count === 0) { + return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_3__["empty"])(); + } + else { + return source.lift(new TakeOperator(count)); + } + }; +} +var TakeOperator = /*@__PURE__*/ (function () { + function TakeOperator(total) { + this.total = total; + if (this.total < 0) { + throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; + } + } + TakeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeSubscriber(subscriber, this.total)); + }; + return TakeOperator; +}()); +var TakeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeSubscriber, _super); + function TakeSubscriber(destination, total) { + var _this = _super.call(this, destination) || this; + _this.total = total; + _this.count = 0; + return _this; + } + TakeSubscriber.prototype._next = function (value) { + var total = this.total; + var count = ++this.count; + if (count <= total) { + this.destination.next(value); + if (count === total) { + this.destination.complete(); + this.unsubscribe(); + } + } + }; + return TakeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=take.js.map + + +/***/ }), +/* 430 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return endWith; }); +/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(79); +/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(44); +/** PURE_IMPORTS_START _observable_concat,_observable_of PURE_IMPORTS_END */ + + +function endWith() { + var array = []; + for (var _i = 0; _i < arguments.length; _i++) { + array[_i] = arguments[_i]; + } + return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(source, _observable_of__WEBPACK_IMPORTED_MODULE_1__["of"].apply(void 0, array)); }; +} +//# sourceMappingURL=endWith.js.map + + +/***/ }), +/* 431 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "every", function() { return every; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function every(predicate, thisArg) { + return function (source) { return source.lift(new EveryOperator(predicate, thisArg, source)); }; +} +var EveryOperator = /*@__PURE__*/ (function () { + function EveryOperator(predicate, thisArg, source) { + this.predicate = predicate; + this.thisArg = thisArg; + this.source = source; + } + EveryOperator.prototype.call = function (observer, source) { + return source.subscribe(new EverySubscriber(observer, this.predicate, this.thisArg, this.source)); + }; + return EveryOperator; +}()); +var EverySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](EverySubscriber, _super); + function EverySubscriber(destination, predicate, thisArg, source) { + var _this = _super.call(this, destination) || this; + _this.predicate = predicate; + _this.thisArg = thisArg; + _this.source = source; + _this.index = 0; + _this.thisArg = thisArg || _this; + return _this; + } + EverySubscriber.prototype.notifyComplete = function (everyValueMatch) { + this.destination.next(everyValueMatch); + this.destination.complete(); + }; + EverySubscriber.prototype._next = function (value) { + var result = false; + try { + result = this.predicate.call(this.thisArg, value, this.index++, this.source); + } + catch (err) { + this.destination.error(err); + return; + } + if (!result) { + this.notifyComplete(false); + } + }; + EverySubscriber.prototype._complete = function () { + this.notifyComplete(true); + }; + return EverySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=every.js.map +/***/ }), +/* 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 _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ -function delay(delay, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; - } - var absoluteDelay = Object(_util_isDate__WEBPACK_IMPORTED_MODULE_2__["isDate"])(delay); - var delayFor = absoluteDelay ? (+delay - scheduler.now()) : Math.abs(delay); - return function (source) { return source.lift(new DelayOperator(delayFor, scheduler)); }; + +function exhaust() { + return function (source) { return source.lift(new SwitchFirstOperator()); }; } -var DelayOperator = /*@__PURE__*/ (function () { - function DelayOperator(delay, scheduler) { - this.delay = delay; - this.scheduler = scheduler; +var SwitchFirstOperator = /*@__PURE__*/ (function () { + function SwitchFirstOperator() { } - DelayOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DelaySubscriber(subscriber, this.delay, this.scheduler)); + SwitchFirstOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SwitchFirstSubscriber(subscriber)); }; - return DelayOperator; + return SwitchFirstOperator; }()); -var DelaySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DelaySubscriber, _super); - function DelaySubscriber(destination, delay, scheduler) { +var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SwitchFirstSubscriber, _super); + function SwitchFirstSubscriber(destination) { var _this = _super.call(this, destination) || this; - _this.delay = delay; - _this.scheduler = scheduler; - _this.queue = []; - _this.active = false; - _this.errored = false; + _this.hasCompleted = false; + _this.hasSubscription = false; return _this; } - DelaySubscriber.dispatch = function (state) { - var source = state.source; - var queue = source.queue; - var scheduler = state.scheduler; - var destination = state.destination; - while (queue.length > 0 && (queue[0].time - scheduler.now()) <= 0) { - queue.shift().notification.observe(destination); + SwitchFirstSubscriber.prototype._next = function (value) { + if (!this.hasSubscription) { + this.hasSubscription = true; + this.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(value, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this))); } - if (queue.length > 0) { - var delay_1 = Math.max(0, queue[0].time - scheduler.now()); - this.schedule(state, delay_1); + }; + SwitchFirstSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (!this.hasSubscription) { + this.destination.complete(); } - else { - this.unsubscribe(); - source.active = false; + }; + SwitchFirstSubscriber.prototype.notifyComplete = function () { + this.hasSubscription = false; + if (this.hasCompleted) { + this.destination.complete(); } }; - DelaySubscriber.prototype._schedule = function (scheduler) { - this.active = true; - var destination = this.destination; - destination.add(scheduler.schedule(DelaySubscriber.dispatch, this.delay, { - source: this, destination: this.destination, scheduler: scheduler - })); + return SwitchFirstSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); +//# sourceMappingURL=exhaust.js.map + + +/***/ }), +/* 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 _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_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)); }; - DelaySubscriber.prototype.scheduleNotification = function (notification) { - if (this.errored === true) { +} +var ExhaustMapOperator = /*@__PURE__*/ (function () { + function ExhaustMapOperator(project) { + this.project = project; + } + ExhaustMapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ExhaustMapSubscriber(subscriber, this.project)); + }; + return ExhaustMapOperator; +}()); +var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExhaustMapSubscriber, _super); + function ExhaustMapSubscriber(destination, project) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.hasSubscription = false; + _this.hasCompleted = false; + _this.index = 0; + return _this; + } + ExhaustMapSubscriber.prototype._next = function (value) { + if (!this.hasSubscription) { + this.tryNext(value); + } + }; + ExhaustMapSubscriber.prototype.tryNext = function (value) { + var result; + var index = this.index++; + try { + result = this.project(value, index); + } + catch (err) { + this.destination.error(err); return; } - var scheduler = this.scheduler; - var message = new DelayMessage(scheduler.now() + this.delay, notification); - this.queue.push(message); - if (this.active === false) { - this._schedule(scheduler); + this.hasSubscription = true; + this._innerSub(result); + }; + 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(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["innerSubscribe"])(result, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + destination.add(innerSubscription); } }; - DelaySubscriber.prototype._next = function (value) { - this.scheduleNotification(_Notification__WEBPACK_IMPORTED_MODULE_4__["Notification"].createNext(value)); + ExhaustMapSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (!this.hasSubscription) { + this.destination.complete(); + } + this.unsubscribe(); }; - DelaySubscriber.prototype._error = function (err) { - this.errored = true; - this.queue = []; + ExhaustMapSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + ExhaustMapSubscriber.prototype.notifyError = function (err) { this.destination.error(err); - this.unsubscribe(); }; - DelaySubscriber.prototype._complete = function () { - this.scheduleNotification(_Notification__WEBPACK_IMPORTED_MODULE_4__["Notification"].createComplete()); - this.unsubscribe(); + ExhaustMapSubscriber.prototype.notifyComplete = function () { + this.hasSubscription = false; + if (this.hasCompleted) { + this.destination.complete(); + } }; - return DelaySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); -var DelayMessage = /*@__PURE__*/ (function () { - function DelayMessage(time, notification) { - this.time = time; - this.notification = notification; - } - return DelayMessage; -}()); -//# sourceMappingURL=delay.js.map + return ExhaustMapSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleOuterSubscriber"])); +//# sourceMappingURL=exhaustMap.js.map /***/ }), -/* 410 */ +/* 434 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isDate", function() { return isDate; }); -/** PURE_IMPORTS_START PURE_IMPORTS_END */ -function isDate(value) { - return value instanceof Date && !isNaN(+value); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return expand; }); +/* 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 _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; + } + concurrent = (concurrent || 0) < 1 ? Number.POSITIVE_INFINITY : concurrent; + return function (source) { return source.lift(new ExpandOperator(project, concurrent, scheduler)); }; } -//# sourceMappingURL=isDate.js.map +var ExpandOperator = /*@__PURE__*/ (function () { + function ExpandOperator(project, concurrent, scheduler) { + this.project = project; + this.concurrent = concurrent; + this.scheduler = scheduler; + } + ExpandOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ExpandSubscriber(subscriber, this.project, this.concurrent, this.scheduler)); + }; + return ExpandOperator; +}()); + +var ExpandSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExpandSubscriber, _super); + function ExpandSubscriber(destination, project, concurrent, scheduler) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.concurrent = concurrent; + _this.scheduler = scheduler; + _this.index = 0; + _this.active = 0; + _this.hasCompleted = false; + if (concurrent < Number.POSITIVE_INFINITY) { + _this.buffer = []; + } + return _this; + } + ExpandSubscriber.dispatch = function (arg) { + var subscriber = arg.subscriber, result = arg.result, value = arg.value, index = arg.index; + subscriber.subscribeToProjection(result, value, index); + }; + ExpandSubscriber.prototype._next = function (value) { + var destination = this.destination; + if (destination.closed) { + this._complete(); + return; + } + var index = this.index++; + if (this.active < this.concurrent) { + destination.next(value); + try { + var project = this.project; + var result = project(value, index); + if (!this.scheduler) { + this.subscribeToProjection(result, value, index); + } + else { + var state = { subscriber: this, result: result, value: value, index: index }; + var destination_1 = this.destination; + destination_1.add(this.scheduler.schedule(ExpandSubscriber.dispatch, 0, state)); + } + } + catch (e) { + destination.error(e); + } + } + else { + this.buffer.push(value); + } + }; + ExpandSubscriber.prototype.subscribeToProjection = function (result, value, index) { + this.active++; + var destination = this.destination; + 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; + if (this.hasCompleted && this.active === 0) { + this.destination.complete(); + } + this.unsubscribe(); + }; + ExpandSubscriber.prototype.notifyNext = function (innerValue) { + this._next(innerValue); + }; + ExpandSubscriber.prototype.notifyComplete = function () { + var buffer = this.buffer; + this.active--; + if (buffer && buffer.length > 0) { + this._next(buffer.shift()); + } + if (this.hasCompleted && this.active === 0) { + this.destination.complete(); + } + }; + return ExpandSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); + +//# sourceMappingURL=expand.js.map /***/ }), -/* 411 */ +/* 435 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return delayWhen; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return finalize; }); /* 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 _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69); -/* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(70); -/** PURE_IMPORTS_START tslib,_Subscriber,_Observable,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17); +/** PURE_IMPORTS_START tslib,_Subscriber,_Subscription PURE_IMPORTS_END */ + + + +function finalize(callback) { + return function (source) { return source.lift(new FinallyOperator(callback)); }; +} +var FinallyOperator = /*@__PURE__*/ (function () { + function FinallyOperator(callback) { + this.callback = callback; + } + FinallyOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new FinallySubscriber(subscriber, this.callback)); + }; + return FinallyOperator; +}()); +var FinallySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FinallySubscriber, _super); + function FinallySubscriber(destination, callback) { + var _this = _super.call(this, destination) || this; + _this.add(new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](callback)); + return _this; + } + return FinallySubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=finalize.js.map +/***/ }), +/* 436 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "find", function() { return find; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FindValueOperator", function() { return FindValueOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FindValueSubscriber", function() { return FindValueSubscriber; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function delayWhen(delayDurationSelector, subscriptionDelay) { - if (subscriptionDelay) { - return function (source) { - return new SubscriptionDelayObservable(source, subscriptionDelay) - .lift(new DelayWhenOperator(delayDurationSelector)); - }; +function find(predicate, thisArg) { + if (typeof predicate !== 'function') { + throw new TypeError('predicate is not a function'); } - return function (source) { return source.lift(new DelayWhenOperator(delayDurationSelector)); }; + return function (source) { return source.lift(new FindValueOperator(predicate, source, false, thisArg)); }; } -var DelayWhenOperator = /*@__PURE__*/ (function () { - function DelayWhenOperator(delayDurationSelector) { - this.delayDurationSelector = delayDurationSelector; +var FindValueOperator = /*@__PURE__*/ (function () { + function FindValueOperator(predicate, source, yieldIndex, thisArg) { + this.predicate = predicate; + this.source = source; + this.yieldIndex = yieldIndex; + this.thisArg = thisArg; } - DelayWhenOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DelayWhenSubscriber(subscriber, this.delayDurationSelector)); + FindValueOperator.prototype.call = function (observer, source) { + return source.subscribe(new FindValueSubscriber(observer, this.predicate, this.source, this.yieldIndex, this.thisArg)); }; - return DelayWhenOperator; + return FindValueOperator; }()); -var DelayWhenSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DelayWhenSubscriber, _super); - function DelayWhenSubscriber(destination, delayDurationSelector) { + +var FindValueSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FindValueSubscriber, _super); + function FindValueSubscriber(destination, predicate, source, yieldIndex, thisArg) { var _this = _super.call(this, destination) || this; - _this.delayDurationSelector = delayDurationSelector; - _this.completed = false; - _this.delayNotifierSubscriptions = []; + _this.predicate = predicate; + _this.source = source; + _this.yieldIndex = yieldIndex; + _this.thisArg = thisArg; _this.index = 0; return _this; } - DelayWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(outerValue); - this.removeSubscription(innerSub); - this.tryComplete(); - }; - DelayWhenSubscriber.prototype.notifyError = function (error, innerSub) { - this._error(error); - }; - DelayWhenSubscriber.prototype.notifyComplete = function (innerSub) { - var value = this.removeSubscription(innerSub); - if (value) { - this.destination.next(value); - } - this.tryComplete(); + FindValueSubscriber.prototype.notifyComplete = function (value) { + var destination = this.destination; + destination.next(value); + destination.complete(); + this.unsubscribe(); }; - DelayWhenSubscriber.prototype._next = function (value) { + FindValueSubscriber.prototype._next = function (value) { + var _a = this, predicate = _a.predicate, thisArg = _a.thisArg; var index = this.index++; try { - var delayNotifier = this.delayDurationSelector(value, index); - if (delayNotifier) { - this.tryDelay(delayNotifier, value); + var result = predicate.call(thisArg || this, value, index, this.source); + if (result) { + this.notifyComplete(this.yieldIndex ? index : value); } } catch (err) { this.destination.error(err); } }; - DelayWhenSubscriber.prototype._complete = function () { - this.completed = true; - this.tryComplete(); - this.unsubscribe(); - }; - DelayWhenSubscriber.prototype.removeSubscription = function (subscription) { - subscription.unsubscribe(); - var subscriptionIdx = this.delayNotifierSubscriptions.indexOf(subscription); - if (subscriptionIdx !== -1) { - this.delayNotifierSubscriptions.splice(subscriptionIdx, 1); - } - return subscription.outerValue; - }; - DelayWhenSubscriber.prototype.tryDelay = function (delayNotifier, value) { - var notifierSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, delayNotifier, value); - if (notifierSubscription && !notifierSubscription.closed) { - var destination = this.destination; - destination.add(notifierSubscription); - this.delayNotifierSubscriptions.push(notifierSubscription); - } - }; - DelayWhenSubscriber.prototype.tryComplete = function () { - if (this.completed && this.delayNotifierSubscriptions.length === 0) { - this.destination.complete(); - } - }; - return DelayWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -var SubscriptionDelayObservable = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscriptionDelayObservable, _super); - function SubscriptionDelayObservable(source, subscriptionDelay) { - var _this = _super.call(this) || this; - _this.source = source; - _this.subscriptionDelay = subscriptionDelay; - return _this; - } - SubscriptionDelayObservable.prototype._subscribe = function (subscriber) { - this.subscriptionDelay.subscribe(new SubscriptionDelaySubscriber(subscriber, this.source)); - }; - return SubscriptionDelayObservable; -}(_Observable__WEBPACK_IMPORTED_MODULE_2__["Observable"])); -var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscriptionDelaySubscriber, _super); - function SubscriptionDelaySubscriber(parent, source) { - var _this = _super.call(this) || this; - _this.parent = parent; - _this.source = source; - _this.sourceSubscribed = false; - return _this; - } - SubscriptionDelaySubscriber.prototype._next = function (unused) { - this.subscribeToSource(); + FindValueSubscriber.prototype._complete = function () { + this.notifyComplete(this.yieldIndex ? -1 : undefined); }; - SubscriptionDelaySubscriber.prototype._error = function (err) { - this.unsubscribe(); - this.parent.error(err); + return FindValueSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); + +//# sourceMappingURL=find.js.map + + +/***/ }), +/* 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__(436); +/** PURE_IMPORTS_START _operators_find PURE_IMPORTS_END */ + +function findIndex(predicate, thisArg) { + return function (source) { return source.lift(new _operators_find__WEBPACK_IMPORTED_MODULE_0__["FindValueOperator"](predicate, source, true, thisArg)); }; +} +//# sourceMappingURL=findIndex.js.map + + +/***/ }), +/* 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__(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 */ + + + + + + +function first(predicate, defaultValue) { + var hasDefaultValue = arguments.length >= 2; + return function (source) { return source.pipe(predicate ? Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return predicate(v, i, source); }) : _util_identity__WEBPACK_IMPORTED_MODULE_5__["identity"], Object(_take__WEBPACK_IMPORTED_MODULE_2__["take"])(1), hasDefaultValue ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__["defaultIfEmpty"])(defaultValue) : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__["throwIfEmpty"])(function () { return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__["EmptyError"](); })); }; +} +//# sourceMappingURL=first.js.map + + +/***/ }), +/* 439 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return ignoreElements; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + +function ignoreElements() { + return function ignoreElementsOperatorFunction(source) { + return source.lift(new IgnoreElementsOperator()); }; - SubscriptionDelaySubscriber.prototype._complete = function () { - this.unsubscribe(); - this.subscribeToSource(); +} +var IgnoreElementsOperator = /*@__PURE__*/ (function () { + function IgnoreElementsOperator() { + } + IgnoreElementsOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new IgnoreElementsSubscriber(subscriber)); }; - SubscriptionDelaySubscriber.prototype.subscribeToSource = function () { - if (!this.sourceSubscribed) { - this.sourceSubscribed = true; - this.unsubscribe(); - this.source.subscribe(this.parent); - } + return IgnoreElementsOperator; +}()); +var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IgnoreElementsSubscriber, _super); + function IgnoreElementsSubscriber() { + return _super !== null && _super.apply(this, arguments) || this; + } + IgnoreElementsSubscriber.prototype._next = function (unused) { }; - return SubscriptionDelaySubscriber; + return IgnoreElementsSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=delayWhen.js.map +//# sourceMappingURL=ignoreElements.js.map /***/ }), -/* 412 */ +/* 440 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return dematerialize; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return isEmpty; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function dematerialize() { - return function dematerializeOperatorFunction(source) { - return source.lift(new DeMaterializeOperator()); - }; +function isEmpty() { + return function (source) { return source.lift(new IsEmptyOperator()); }; } -var DeMaterializeOperator = /*@__PURE__*/ (function () { - function DeMaterializeOperator() { +var IsEmptyOperator = /*@__PURE__*/ (function () { + function IsEmptyOperator() { } - DeMaterializeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DeMaterializeSubscriber(subscriber)); + IsEmptyOperator.prototype.call = function (observer, source) { + return source.subscribe(new IsEmptySubscriber(observer)); }; - return DeMaterializeOperator; + return IsEmptyOperator; }()); -var DeMaterializeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DeMaterializeSubscriber, _super); - function DeMaterializeSubscriber(destination) { +var IsEmptySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IsEmptySubscriber, _super); + function IsEmptySubscriber(destination) { return _super.call(this, destination) || this; } - DeMaterializeSubscriber.prototype._next = function (value) { - value.observe(this.destination); + IsEmptySubscriber.prototype.notifyComplete = function (isEmpty) { + var destination = this.destination; + destination.next(isEmpty); + destination.complete(); }; - return DeMaterializeSubscriber; + IsEmptySubscriber.prototype._next = function (value) { + this.notifyComplete(false); + }; + IsEmptySubscriber.prototype._complete = function () { + this.notifyComplete(true); + }; + return IsEmptySubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=dematerialize.js.map +//# sourceMappingURL=isEmpty.js.map /***/ }), -/* 413 */ +/* 441 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __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 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__(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 */ + + + + + + +function last(predicate, defaultValue) { + var hasDefaultValue = arguments.length >= 2; + return function (source) { return source.pipe(predicate ? Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return predicate(v, i, source); }) : _util_identity__WEBPACK_IMPORTED_MODULE_5__["identity"], Object(_takeLast__WEBPACK_IMPORTED_MODULE_2__["takeLast"])(1), hasDefaultValue ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__["defaultIfEmpty"])(defaultValue) : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__["throwIfEmpty"])(function () { return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__["EmptyError"](); })); }; +} +//# sourceMappingURL=last.js.map + + +/***/ }), +/* 442 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return takeLast; }); /* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(62); +/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(43); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ -function distinct(keySelector, flushes) { - return function (source) { return source.lift(new DistinctOperator(keySelector, flushes)); }; + +function takeLast(count) { + return function takeLastOperatorFunction(source) { + if (count === 0) { + return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_3__["empty"])(); + } + else { + return source.lift(new TakeLastOperator(count)); + } + }; } -var DistinctOperator = /*@__PURE__*/ (function () { - function DistinctOperator(keySelector, flushes) { - this.keySelector = keySelector; - this.flushes = flushes; +var TakeLastOperator = /*@__PURE__*/ (function () { + function TakeLastOperator(total) { + this.total = total; + if (this.total < 0) { + throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; + } } - DistinctOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DistinctSubscriber(subscriber, this.keySelector, this.flushes)); + TakeLastOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeLastSubscriber(subscriber, this.total)); }; - return DistinctOperator; + return TakeLastOperator; }()); -var DistinctSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DistinctSubscriber, _super); - function DistinctSubscriber(destination, keySelector, flushes) { +var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeLastSubscriber, _super); + function TakeLastSubscriber(destination, total) { var _this = _super.call(this, destination) || this; - _this.keySelector = keySelector; - _this.values = new Set(); - if (flushes) { - _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, flushes)); - } + _this.total = total; + _this.ring = new Array(); + _this.count = 0; return _this; } - DistinctSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.values.clear(); - }; - DistinctSubscriber.prototype.notifyError = function (error, innerSub) { - this._error(error); - }; - DistinctSubscriber.prototype._next = function (value) { - if (this.keySelector) { - this._useKeySelector(value); + TakeLastSubscriber.prototype._next = function (value) { + var ring = this.ring; + var total = this.total; + var count = this.count++; + if (ring.length < total) { + ring.push(value); } else { - this._finalizeNext(value, value); + var index = count % total; + ring[index] = value; } }; - DistinctSubscriber.prototype._useKeySelector = function (value) { - var key; + TakeLastSubscriber.prototype._complete = function () { var destination = this.destination; - try { - key = this.keySelector(value); - } - catch (err) { - destination.error(err); - return; - } - this._finalizeNext(key, value); - }; - DistinctSubscriber.prototype._finalizeNext = function (key, value) { - var values = this.values; - if (!values.has(key)) { - values.add(key); - this.destination.next(value); + var count = this.count; + if (count > 0) { + var total = this.count >= this.total ? this.total : this.count; + var ring = this.ring; + for (var i = 0; i < total; i++) { + var idx = (count++) % total; + destination.next(ring[idx]); + } } + destination.complete(); }; - return DistinctSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); - -//# sourceMappingURL=distinct.js.map + return TakeLastSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=takeLast.js.map /***/ }), -/* 414 */ +/* 443 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return distinctUntilChanged; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return mapTo; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function distinctUntilChanged(compare, keySelector) { - return function (source) { return source.lift(new DistinctUntilChangedOperator(compare, keySelector)); }; +function mapTo(value) { + return function (source) { return source.lift(new MapToOperator(value)); }; } -var DistinctUntilChangedOperator = /*@__PURE__*/ (function () { - function DistinctUntilChangedOperator(compare, keySelector) { - this.compare = compare; - this.keySelector = keySelector; +var MapToOperator = /*@__PURE__*/ (function () { + function MapToOperator(value) { + this.value = value; } - DistinctUntilChangedOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new DistinctUntilChangedSubscriber(subscriber, this.compare, this.keySelector)); + MapToOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MapToSubscriber(subscriber, this.value)); }; - return DistinctUntilChangedOperator; + return MapToOperator; }()); -var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](DistinctUntilChangedSubscriber, _super); - function DistinctUntilChangedSubscriber(destination, compare, keySelector) { +var MapToSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MapToSubscriber, _super); + function MapToSubscriber(destination, value) { var _this = _super.call(this, destination) || this; - _this.keySelector = keySelector; - _this.hasKey = false; - if (typeof compare === 'function') { - _this.compare = compare; - } + _this.value = value; return _this; } - DistinctUntilChangedSubscriber.prototype.compare = function (x, y) { - return x === y; - }; - DistinctUntilChangedSubscriber.prototype._next = function (value) { - var key; - try { - var keySelector = this.keySelector; - key = keySelector ? keySelector(value) : value; - } - catch (err) { - return this.destination.error(err); - } - var result = false; - if (this.hasKey) { - try { - var compare = this.compare; - result = compare(this.key, key); - } - catch (err) { - return this.destination.error(err); - } - } - else { - this.hasKey = true; - } - if (!result) { - this.key = key; - this.destination.next(value); - } + MapToSubscriber.prototype._next = function (x) { + this.destination.next(this.value); }; - return DistinctUntilChangedSubscriber; + return MapToSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=distinctUntilChanged.js.map +//# sourceMappingURL=mapTo.js.map /***/ }), -/* 415 */ +/* 444 */ /***/ (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__(414); -/** PURE_IMPORTS_START _distinctUntilChanged PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return materialize; }); +/* 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 _Notification__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(42); +/** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ -function distinctUntilKeyChanged(key, compare) { - return Object(_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__["distinctUntilChanged"])(function (x, y) { return compare ? compare(x[key], y[key]) : x[key] === y[key]; }); + + +function materialize() { + return function materializeOperatorFunction(source) { + return source.lift(new MaterializeOperator()); + }; } -//# sourceMappingURL=distinctUntilKeyChanged.js.map +var MaterializeOperator = /*@__PURE__*/ (function () { + function MaterializeOperator() { + } + MaterializeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MaterializeSubscriber(subscriber)); + }; + return MaterializeOperator; +}()); +var MaterializeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MaterializeSubscriber, _super); + function MaterializeSubscriber(destination) { + return _super.call(this, destination) || this; + } + MaterializeSubscriber.prototype._next = function (value) { + this.destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createNext(value)); + }; + MaterializeSubscriber.prototype._error = function (err) { + var destination = this.destination; + destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createError(err)); + destination.complete(); + }; + MaterializeSubscriber.prototype._complete = function () { + var destination = this.destination; + destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createComplete()); + destination.complete(); + }; + return MaterializeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=materialize.js.map /***/ }), -/* 416 */ +/* 445 */ /***/ (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__(417); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(408); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(418); -/** PURE_IMPORTS_START _util_ArgumentOutOfRangeError,_filter,_throwIfEmpty,_defaultIfEmpty,_take PURE_IMPORTS_END */ - - - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return max; }); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(446); +/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ -function elementAt(index, defaultValue) { - if (index < 0) { - throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__["ArgumentOutOfRangeError"](); - } - var hasDefaultValue = arguments.length >= 2; - return function (source) { - return source.pipe(Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return i === index; }), Object(_take__WEBPACK_IMPORTED_MODULE_4__["take"])(1), hasDefaultValue - ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__["defaultIfEmpty"])(defaultValue) - : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__["throwIfEmpty"])(function () { return new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__["ArgumentOutOfRangeError"](); })); - }; +function max(comparer) { + var max = (typeof comparer === 'function') + ? function (x, y) { return comparer(x, y) > 0 ? x : y; } + : function (x, y) { return x > y ? x : y; }; + return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(max); } -//# sourceMappingURL=elementAt.js.map +//# sourceMappingURL=max.js.map /***/ }), -/* 417 */ +/* 446 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return throwIfEmpty; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(63); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_util_EmptyError,_Subscriber PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return reduce; }); +/* 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 */ -function throwIfEmpty(errorFactory) { - if (errorFactory === void 0) { - errorFactory = defaultErrorFactory; - } - return function (source) { - return source.lift(new ThrowIfEmptyOperator(errorFactory)); - }; -} -var ThrowIfEmptyOperator = /*@__PURE__*/ (function () { - function ThrowIfEmptyOperator(errorFactory) { - this.errorFactory = errorFactory; - } - ThrowIfEmptyOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ThrowIfEmptySubscriber(subscriber, this.errorFactory)); - }; - return ThrowIfEmptyOperator; -}()); -var ThrowIfEmptySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrowIfEmptySubscriber, _super); - function ThrowIfEmptySubscriber(destination, errorFactory) { - var _this = _super.call(this, destination) || this; - _this.errorFactory = errorFactory; - _this.hasValue = false; - return _this; + +function reduce(accumulator, seed) { + if (arguments.length >= 2) { + return function reduceOperatorFunctionWithSeed(source) { + return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipe"])(Object(_scan__WEBPACK_IMPORTED_MODULE_0__["scan"])(accumulator, seed), Object(_takeLast__WEBPACK_IMPORTED_MODULE_1__["takeLast"])(1), Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__["defaultIfEmpty"])(seed))(source); + }; } - ThrowIfEmptySubscriber.prototype._next = function (value) { - this.hasValue = true; - this.destination.next(value); - }; - ThrowIfEmptySubscriber.prototype._complete = function () { - if (!this.hasValue) { - var err = void 0; - try { - err = this.errorFactory(); - } - catch (e) { - err = e; - } - this.destination.error(err); - } - else { - return this.destination.complete(); - } + return function reduceOperatorFunction(source) { + return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipe"])(Object(_scan__WEBPACK_IMPORTED_MODULE_0__["scan"])(function (acc, value, index) { return accumulator(acc, value, index + 1); }), Object(_takeLast__WEBPACK_IMPORTED_MODULE_1__["takeLast"])(1))(source); }; - return ThrowIfEmptySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_2__["Subscriber"])); -function defaultErrorFactory() { - return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__["EmptyError"](); } -//# sourceMappingURL=throwIfEmpty.js.map +//# sourceMappingURL=reduce.js.map /***/ }), -/* 418 */ +/* 447 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "take", function() { return take; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return scan; }); /* 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 _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(62); -/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(43); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ - - +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function take(count) { - return function (source) { - if (count === 0) { - return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_3__["empty"])(); - } - else { - return source.lift(new TakeOperator(count)); - } +function scan(accumulator, seed) { + var hasSeed = false; + if (arguments.length >= 2) { + hasSeed = true; + } + return function scanOperatorFunction(source) { + return source.lift(new ScanOperator(accumulator, seed, hasSeed)); }; } -var TakeOperator = /*@__PURE__*/ (function () { - function TakeOperator(total) { - this.total = total; - if (this.total < 0) { - throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; +var ScanOperator = /*@__PURE__*/ (function () { + function ScanOperator(accumulator, seed, hasSeed) { + if (hasSeed === void 0) { + hasSeed = false; } + this.accumulator = accumulator; + this.seed = seed; + this.hasSeed = hasSeed; } - TakeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TakeSubscriber(subscriber, this.total)); + ScanOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ScanSubscriber(subscriber, this.accumulator, this.seed, this.hasSeed)); }; - return TakeOperator; + return ScanOperator; }()); -var TakeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeSubscriber, _super); - function TakeSubscriber(destination, total) { +var ScanSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ScanSubscriber, _super); + function ScanSubscriber(destination, accumulator, _seed, hasSeed) { var _this = _super.call(this, destination) || this; - _this.total = total; - _this.count = 0; + _this.accumulator = accumulator; + _this._seed = _seed; + _this.hasSeed = hasSeed; + _this.index = 0; return _this; } - TakeSubscriber.prototype._next = function (value) { - var total = this.total; - var count = ++this.count; - if (count <= total) { + Object.defineProperty(ScanSubscriber.prototype, "seed", { + get: function () { + return this._seed; + }, + set: function (value) { + this.hasSeed = true; + this._seed = value; + }, + enumerable: true, + configurable: true + }); + ScanSubscriber.prototype._next = function (value) { + if (!this.hasSeed) { + this.seed = value; this.destination.next(value); - if (count === total) { - this.destination.complete(); - this.unsubscribe(); - } + } + else { + return this._tryNext(value); } }; - return TakeSubscriber; + ScanSubscriber.prototype._tryNext = function (value) { + var index = this.index++; + var result; + try { + result = this.accumulator(this.seed, value, index); + } + catch (err) { + this.destination.error(err); + } + this.seed = result; + this.destination.next(result); + }; + return ScanSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=take.js.map +//# sourceMappingURL=scan.js.map + + +/***/ }), +/* 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__(99); +/** PURE_IMPORTS_START _observable_merge PURE_IMPORTS_END */ + +function merge() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + return function (source) { return source.lift.call(_observable_merge__WEBPACK_IMPORTED_MODULE_0__["merge"].apply(void 0, [source].concat(observables))); }; +} +//# sourceMappingURL=merge.js.map /***/ }), -/* 419 */ +/* 449 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return endWith; }); -/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(79); -/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(44); -/** PURE_IMPORTS_START _observable_concat,_observable_of PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return mergeMapTo; }); +/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82); +/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ -function endWith() { - var array = []; - for (var _i = 0; _i < arguments.length; _i++) { - array[_i] = arguments[_i]; +function mergeMapTo(innerObservable, resultSelector, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; } - return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(source, _observable_of__WEBPACK_IMPORTED_MODULE_1__["of"].apply(void 0, array)); }; + if (typeof resultSelector === 'function') { + return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(function () { return innerObservable; }, resultSelector, concurrent); + } + if (typeof resultSelector === 'number') { + concurrent = resultSelector; + } + return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(function () { return innerObservable; }, concurrent); } -//# sourceMappingURL=endWith.js.map +//# sourceMappingURL=mergeMapTo.js.map /***/ }), -/* 420 */ +/* 450 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "every", function() { return every; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return mergeScan; }); +/* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ -function every(predicate, thisArg) { - return function (source) { return source.lift(new EveryOperator(predicate, thisArg, source)); }; +function mergeScan(accumulator, seed, concurrent) { + if (concurrent === void 0) { + concurrent = Number.POSITIVE_INFINITY; + } + return function (source) { return source.lift(new MergeScanOperator(accumulator, seed, concurrent)); }; } -var EveryOperator = /*@__PURE__*/ (function () { - function EveryOperator(predicate, thisArg, source) { - this.predicate = predicate; - this.thisArg = thisArg; - this.source = source; +var MergeScanOperator = /*@__PURE__*/ (function () { + function MergeScanOperator(accumulator, seed, concurrent) { + this.accumulator = accumulator; + this.seed = seed; + this.concurrent = concurrent; } - EveryOperator.prototype.call = function (observer, source) { - return source.subscribe(new EverySubscriber(observer, this.predicate, this.thisArg, this.source)); + MergeScanOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new MergeScanSubscriber(subscriber, this.accumulator, this.seed, this.concurrent)); }; - return EveryOperator; + return MergeScanOperator; }()); -var EverySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](EverySubscriber, _super); - function EverySubscriber(destination, predicate, thisArg, source) { + +var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MergeScanSubscriber, _super); + function MergeScanSubscriber(destination, accumulator, acc, concurrent) { var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.thisArg = thisArg; - _this.source = source; + _this.accumulator = accumulator; + _this.acc = acc; + _this.concurrent = concurrent; + _this.hasValue = false; + _this.hasCompleted = false; + _this.buffer = []; + _this.active = 0; _this.index = 0; - _this.thisArg = thisArg || _this; return _this; } - EverySubscriber.prototype.notifyComplete = function (everyValueMatch) { - this.destination.next(everyValueMatch); - this.destination.complete(); - }; - EverySubscriber.prototype._next = function (value) { - var result = false; - try { - result = this.predicate.call(this.thisArg, value, this.index++, this.source); + MergeScanSubscriber.prototype._next = function (value) { + if (this.active < this.concurrent) { + var index = this.index++; + var destination = this.destination; + var ish = void 0; + try { + var accumulator = this.accumulator; + ish = accumulator(this.acc, value, index); + } + catch (e) { + return destination.error(e); + } + this.active++; + this._innerSub(ish); } - catch (err) { - this.destination.error(err); - return; + else { + this.buffer.push(value); } - if (!result) { - this.notifyComplete(false); + }; + 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(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(ish, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + destination.add(innerSubscription); } }; - EverySubscriber.prototype._complete = function () { - this.notifyComplete(true); + MergeScanSubscriber.prototype._complete = function () { + this.hasCompleted = true; + if (this.active === 0 && this.buffer.length === 0) { + if (this.hasValue === false) { + this.destination.next(this.acc); + } + this.destination.complete(); + } + this.unsubscribe(); }; - return EverySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=every.js.map + MergeScanSubscriber.prototype.notifyNext = function (innerValue) { + var destination = this.destination; + this.acc = innerValue; + this.hasValue = true; + destination.next(innerValue); + }; + MergeScanSubscriber.prototype.notifyComplete = function () { + var buffer = this.buffer; + this.active--; + if (buffer.length > 0) { + this._next(buffer.shift()); + } + else if (this.active === 0 && this.hasCompleted) { + if (this.hasValue === false) { + this.destination.next(this.acc); + } + this.destination.complete(); + } + }; + return MergeScanSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); + +//# sourceMappingURL=mergeScan.js.map /***/ }), -/* 421 */ +/* 451 */ /***/ (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 export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return min; }); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(446); +/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ +function min(comparer) { + var min = (typeof comparer === 'function') + ? function (x, y) { return comparer(x, y) < 0 ? x : y; } + : function (x, y) { return x < y ? x : y; }; + return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(min); +} +//# sourceMappingURL=min.js.map -function exhaust() { - return function (source) { return source.lift(new SwitchFirstOperator()); }; -} -var SwitchFirstOperator = /*@__PURE__*/ (function () { - function SwitchFirstOperator() { - } - SwitchFirstOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SwitchFirstSubscriber(subscriber)); - }; - return SwitchFirstOperator; -}()); -var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SwitchFirstSubscriber, _super); - function SwitchFirstSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.hasCompleted = false; - _this.hasSubscription = false; - return _this; - } - SwitchFirstSubscriber.prototype._next = function (value) { - if (!this.hasSubscription) { - this.hasSubscription = true; - this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(this, value)); +/***/ }), +/* 452 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return multicast; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MulticastOperator", function() { return MulticastOperator; }); +/* harmony import */ var _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26); +/** PURE_IMPORTS_START _observable_ConnectableObservable PURE_IMPORTS_END */ + +function multicast(subjectOrSubjectFactory, selector) { + return function multicastOperatorFunction(source) { + var subjectFactory; + if (typeof subjectOrSubjectFactory === 'function') { + subjectFactory = subjectOrSubjectFactory; } - }; - SwitchFirstSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (!this.hasSubscription) { - this.destination.complete(); + else { + subjectFactory = function subjectFactory() { + return subjectOrSubjectFactory; + }; } - }; - SwitchFirstSubscriber.prototype.notifyComplete = function (innerSub) { - this.remove(innerSub); - this.hasSubscription = false; - if (this.hasCompleted) { - this.destination.complete(); + if (typeof selector === 'function') { + return source.lift(new MulticastOperator(subjectFactory, selector)); } + var connectable = Object.create(source, _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__["connectableObservableDescriptor"]); + connectable.source = source; + connectable.subjectFactory = subjectFactory; + return connectable; }; - return SwitchFirstSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=exhaust.js.map +} +var MulticastOperator = /*@__PURE__*/ (function () { + function MulticastOperator(subjectFactory, selector) { + this.subjectFactory = subjectFactory; + this.selector = selector; + } + MulticastOperator.prototype.call = function (subscriber, source) { + var selector = this.selector; + var subject = this.subjectFactory(); + var subscription = selector(subject).subscribe(subscriber); + subscription.add(source.subscribe(subject)); + return subscription; + }; + return MulticastOperator; +}()); + +//# sourceMappingURL=multicast.js.map /***/ }), -/* 422 */ +/* 453 */ /***/ (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 export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return onErrorResumeNext; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNextStatic", function() { return onErrorResumeNextStatic; }); /* 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 _observable_from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(83); +/* harmony import */ var _util_isArray__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(18); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_observable_from,_util_isArray,_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); })); })); }; +function onErrorResumeNext() { + var nextSources = []; + for (var _i = 0; _i < arguments.length; _i++) { + nextSources[_i] = arguments[_i]; } - return function (source) { - return source.lift(new ExhaustMapOperator(project)); - }; + if (nextSources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(nextSources[0])) { + nextSources = nextSources[0]; + } + return function (source) { return source.lift(new OnErrorResumeNextOperator(nextSources)); }; } -var ExhaustMapOperator = /*@__PURE__*/ (function () { - function ExhaustMapOperator(project) { - this.project = project; +function onErrorResumeNextStatic() { + var nextSources = []; + for (var _i = 0; _i < arguments.length; _i++) { + nextSources[_i] = arguments[_i]; } - ExhaustMapOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ExhaustMapSubscriber(subscriber, this.project)); + 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).lift(new OnErrorResumeNextOperator(nextSources)); +} +var OnErrorResumeNextOperator = /*@__PURE__*/ (function () { + function OnErrorResumeNextOperator(nextSources) { + this.nextSources = nextSources; + } + OnErrorResumeNextOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new OnErrorResumeNextSubscriber(subscriber, this.nextSources)); }; - return ExhaustMapOperator; + return OnErrorResumeNextOperator; }()); -var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExhaustMapSubscriber, _super); - function ExhaustMapSubscriber(destination, project) { +var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](OnErrorResumeNextSubscriber, _super); + function OnErrorResumeNextSubscriber(destination, nextSources) { var _this = _super.call(this, destination) || this; - _this.project = project; - _this.hasSubscription = false; - _this.hasCompleted = false; - _this.index = 0; + _this.destination = destination; + _this.nextSources = nextSources; return _this; } - ExhaustMapSubscriber.prototype._next = function (value) { - if (!this.hasSubscription) { - this.tryNext(value); - } - }; - ExhaustMapSubscriber.prototype.tryNext = function (value) { - var result; - var index = this.index++; - try { - result = this.project(value, index); - } - catch (err) { - this.destination.error(err); - return; - } - this.hasSubscription = true; - this._innerSub(result, value, index); + OnErrorResumeNextSubscriber.prototype.notifyError = function () { + this.subscribeToNextSource(); }; - ExhaustMapSubscriber.prototype._innerSub = function (result, value, index) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, value, index); - var destination = this.destination; - destination.add(innerSubscriber); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, undefined, undefined, innerSubscriber); - if (innerSubscription !== innerSubscriber) { - destination.add(innerSubscription); - } + OnErrorResumeNextSubscriber.prototype.notifyComplete = function () { + this.subscribeToNextSource(); }; - ExhaustMapSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (!this.hasSubscription) { - this.destination.complete(); - } + OnErrorResumeNextSubscriber.prototype._error = function (err) { + this.subscribeToNextSource(); this.unsubscribe(); }; - ExhaustMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(innerValue); - }; - ExhaustMapSubscriber.prototype.notifyError = function (err) { - this.destination.error(err); + OnErrorResumeNextSubscriber.prototype._complete = function () { + this.subscribeToNextSource(); + this.unsubscribe(); }; - ExhaustMapSubscriber.prototype.notifyComplete = function (innerSub) { - var destination = this.destination; - destination.remove(innerSub); - this.hasSubscription = false; - if (this.hasCompleted) { + OnErrorResumeNextSubscriber.prototype.subscribeToNextSource = function () { + var next = this.nextSources.shift(); + if (!!next) { + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleInnerSubscriber"](this); + var destination = this.destination; + destination.add(innerSubscriber); + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["innerSubscribe"])(next, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + destination.add(innerSubscription); + } + } + else { this.destination.complete(); } }; - return ExhaustMapSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=exhaustMap.js.map + return OnErrorResumeNextSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleOuterSubscriber"])); +//# sourceMappingURL=onErrorResumeNext.js.map /***/ }), -/* 423 */ +/* 454 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return expand; }); -/* 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 export (binding) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return pairwise; }); /* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber 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)); }; +function pairwise() { + return function (source) { return source.lift(new PairwiseOperator()); }; } -var ExpandOperator = /*@__PURE__*/ (function () { - function ExpandOperator(project, concurrent, scheduler) { - this.project = project; - this.concurrent = concurrent; - this.scheduler = scheduler; +var PairwiseOperator = /*@__PURE__*/ (function () { + function PairwiseOperator() { } - ExpandOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ExpandSubscriber(subscriber, this.project, this.concurrent, this.scheduler)); + PairwiseOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new PairwiseSubscriber(subscriber)); }; - return ExpandOperator; + return PairwiseOperator; }()); - -var ExpandSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ExpandSubscriber, _super); - function ExpandSubscriber(destination, project, concurrent, scheduler) { +var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PairwiseSubscriber, _super); + function PairwiseSubscriber(destination) { var _this = _super.call(this, destination) || this; - _this.project = project; - _this.concurrent = concurrent; - _this.scheduler = scheduler; - _this.index = 0; - _this.active = 0; - _this.hasCompleted = false; - if (concurrent < Number.POSITIVE_INFINITY) { - _this.buffer = []; - } + _this.hasPrev = false; return _this; } - ExpandSubscriber.dispatch = function (arg) { - var subscriber = arg.subscriber, result = arg.result, value = arg.value, index = arg.index; - subscriber.subscribeToProjection(result, value, index); - }; - ExpandSubscriber.prototype._next = function (value) { - var destination = this.destination; - if (destination.closed) { - this._complete(); - return; - } - var index = this.index++; - if (this.active < this.concurrent) { - destination.next(value); - try { - var project = this.project; - var result = project(value, index); - if (!this.scheduler) { - this.subscribeToProjection(result, value, index); - } - else { - var state = { subscriber: this, result: result, value: value, index: index }; - var destination_1 = this.destination; - destination_1.add(this.scheduler.schedule(ExpandSubscriber.dispatch, 0, state)); - } - } - catch (e) { - destination.error(e); - } + PairwiseSubscriber.prototype._next = function (value) { + var pair; + if (this.hasPrev) { + pair = [this.prev, value]; } else { - this.buffer.push(value); + this.hasPrev = true; } - }; - 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)); - }; - ExpandSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (this.hasCompleted && this.active === 0) { - this.destination.complete(); + this.prev = value; + if (pair) { + this.destination.next(pair); } - this.unsubscribe(); }; - ExpandSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this._next(innerValue); + return PairwiseSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=pairwise.js.map + + +/***/ }), +/* 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__(104); +/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(105); +/** PURE_IMPORTS_START _util_not,_filter PURE_IMPORTS_END */ + + +function partition(predicate, thisArg) { + return function (source) { + return [ + Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(predicate, thisArg)(source), + Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(Object(_util_not__WEBPACK_IMPORTED_MODULE_0__["not"])(predicate, thisArg))(source) + ]; }; - ExpandSubscriber.prototype.notifyComplete = function (innerSub) { - var buffer = this.buffer; - var destination = this.destination; - destination.remove(innerSub); - this.active--; - if (buffer && buffer.length > 0) { - this._next(buffer.shift()); - } - if (this.hasCompleted && this.active === 0) { - this.destination.complete(); +} +//# sourceMappingURL=partition.js.map + + +/***/ }), +/* 456 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return pluck; }); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(66); +/** PURE_IMPORTS_START _map PURE_IMPORTS_END */ + +function pluck() { + var properties = []; + for (var _i = 0; _i < arguments.length; _i++) { + properties[_i] = arguments[_i]; + } + var length = properties.length; + if (length === 0) { + throw new Error('list of properties cannot be empty.'); + } + return function (source) { return Object(_map__WEBPACK_IMPORTED_MODULE_0__["map"])(plucker(properties, length))(source); }; +} +function plucker(props, length) { + var mapper = function (x) { + var currentProp = x; + for (var i = 0; i < length; i++) { + var p = currentProp != null ? currentProp[props[i]] : undefined; + if (p !== void 0) { + currentProp = p; + } + else { + return undefined; + } } + return currentProp; }; - return ExpandSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); - -//# sourceMappingURL=expand.js.map + return mapper; +} +//# sourceMappingURL=pluck.js.map /***/ }), -/* 424 */ +/* 457 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return finalize; }); -/* 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 _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17); -/** PURE_IMPORTS_START tslib,_Subscriber,_Subscription PURE_IMPORTS_END */ - +/* 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__(452); +/** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ -function finalize(callback) { - return function (source) { return source.lift(new FinallyOperator(callback)); }; +function publish(selector) { + return selector ? + Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(function () { return new _Subject__WEBPACK_IMPORTED_MODULE_0__["Subject"](); }, selector) : + Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _Subject__WEBPACK_IMPORTED_MODULE_0__["Subject"]()); } -var FinallyOperator = /*@__PURE__*/ (function () { - function FinallyOperator(callback) { - this.callback = callback; - } - FinallyOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new FinallySubscriber(subscriber, this.callback)); - }; - return FinallyOperator; -}()); -var FinallySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FinallySubscriber, _super); - function FinallySubscriber(destination, callback) { - var _this = _super.call(this, destination) || this; - _this.add(new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](callback)); - return _this; - } - return FinallySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=finalize.js.map +//# sourceMappingURL=publish.js.map /***/ }), -/* 425 */ +/* 458 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "find", function() { return find; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FindValueOperator", function() { return FindValueOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FindValueSubscriber", function() { return FindValueSubscriber; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* 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__(452); +/** PURE_IMPORTS_START _BehaviorSubject,_multicast PURE_IMPORTS_END */ -function find(predicate, thisArg) { - if (typeof predicate !== 'function') { - throw new TypeError('predicate is not a function'); - } - return function (source) { return source.lift(new FindValueOperator(predicate, source, false, thisArg)); }; +function publishBehavior(value) { + return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__["BehaviorSubject"](value))(source); }; } -var FindValueOperator = /*@__PURE__*/ (function () { - function FindValueOperator(predicate, source, yieldIndex, thisArg) { - this.predicate = predicate; - this.source = source; - this.yieldIndex = yieldIndex; - this.thisArg = thisArg; - } - FindValueOperator.prototype.call = function (observer, source) { - return source.subscribe(new FindValueSubscriber(observer, this.predicate, this.source, this.yieldIndex, this.thisArg)); - }; - return FindValueOperator; -}()); - -var FindValueSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](FindValueSubscriber, _super); - function FindValueSubscriber(destination, predicate, source, yieldIndex, thisArg) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.source = source; - _this.yieldIndex = yieldIndex; - _this.thisArg = thisArg; - _this.index = 0; - return _this; - } - FindValueSubscriber.prototype.notifyComplete = function (value) { - var destination = this.destination; - destination.next(value); - destination.complete(); - this.unsubscribe(); - }; - FindValueSubscriber.prototype._next = function (value) { - var _a = this, predicate = _a.predicate, thisArg = _a.thisArg; - var index = this.index++; - try { - var result = predicate.call(thisArg || this, value, index, this.source); - if (result) { - this.notifyComplete(this.yieldIndex ? index : value); - } - } - catch (err) { - this.destination.error(err); - } - }; - FindValueSubscriber.prototype._complete = function () { - this.notifyComplete(this.yieldIndex ? -1 : undefined); - }; - return FindValueSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); - -//# sourceMappingURL=find.js.map +//# sourceMappingURL=publishBehavior.js.map /***/ }), -/* 426 */ +/* 459 */ /***/ (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__(425); -/** PURE_IMPORTS_START _operators_find PURE_IMPORTS_END */ +/* 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__(452); +/** PURE_IMPORTS_START _AsyncSubject,_multicast PURE_IMPORTS_END */ -function findIndex(predicate, thisArg) { - return function (source) { return source.lift(new _operators_find__WEBPACK_IMPORTED_MODULE_0__["FindValueOperator"](predicate, source, true, thisArg)); }; + +function publishLast() { + return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__["AsyncSubject"]())(source); }; } -//# sourceMappingURL=findIndex.js.map +//# sourceMappingURL=publishLast.js.map /***/ }), -/* 427 */ +/* 460 */ /***/ (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__(418); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(408); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(417); -/* 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 */ +/* 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__(452); +/** PURE_IMPORTS_START _ReplaySubject,_multicast PURE_IMPORTS_END */ +function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) { + if (selectorOrScheduler && typeof selectorOrScheduler !== 'function') { + scheduler = selectorOrScheduler; + } + var selector = typeof selectorOrScheduler === 'function' ? selectorOrScheduler : undefined; + var subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__["ReplaySubject"](bufferSize, windowTime, scheduler); + return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(function () { return subject; }, selector)(source); }; +} +//# sourceMappingURL=publishReplay.js.map + +/***/ }), +/* 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__(106); +/** PURE_IMPORTS_START _util_isArray,_observable_race PURE_IMPORTS_END */ -function first(predicate, defaultValue) { - var hasDefaultValue = arguments.length >= 2; - return function (source) { return source.pipe(predicate ? Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return predicate(v, i, source); }) : _util_identity__WEBPACK_IMPORTED_MODULE_5__["identity"], Object(_take__WEBPACK_IMPORTED_MODULE_2__["take"])(1), hasDefaultValue ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__["defaultIfEmpty"])(defaultValue) : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__["throwIfEmpty"])(function () { return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__["EmptyError"](); })); }; +function race() { + var observables = []; + for (var _i = 0; _i < arguments.length; _i++) { + observables[_i] = arguments[_i]; + } + return function raceOperatorFunction(source) { + if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(observables[0])) { + observables = observables[0]; + } + return source.lift.call(_observable_race__WEBPACK_IMPORTED_MODULE_1__["race"].apply(void 0, [source].concat(observables))); + }; } -//# sourceMappingURL=first.js.map +//# sourceMappingURL=race.js.map /***/ }), -/* 428 */ +/* 462 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return ignoreElements; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return repeat; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(43); +/** PURE_IMPORTS_START tslib,_Subscriber,_observable_empty PURE_IMPORTS_END */ -function ignoreElements() { - return function ignoreElementsOperatorFunction(source) { - return source.lift(new IgnoreElementsOperator()); + +function repeat(count) { + if (count === void 0) { + count = -1; + } + return function (source) { + if (count === 0) { + return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_2__["empty"])(); + } + else if (count < 0) { + return source.lift(new RepeatOperator(-1, source)); + } + else { + return source.lift(new RepeatOperator(count - 1, source)); + } }; } -var IgnoreElementsOperator = /*@__PURE__*/ (function () { - function IgnoreElementsOperator() { +var RepeatOperator = /*@__PURE__*/ (function () { + function RepeatOperator(count, source) { + this.count = count; + this.source = source; } - IgnoreElementsOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new IgnoreElementsSubscriber(subscriber)); + RepeatOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RepeatSubscriber(subscriber, this.count, this.source)); }; - return IgnoreElementsOperator; + return RepeatOperator; }()); -var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IgnoreElementsSubscriber, _super); - function IgnoreElementsSubscriber() { - return _super !== null && _super.apply(this, arguments) || this; +var RepeatSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RepeatSubscriber, _super); + function RepeatSubscriber(destination, count, source) { + var _this = _super.call(this, destination) || this; + _this.count = count; + _this.source = source; + return _this; } - IgnoreElementsSubscriber.prototype._next = function (unused) { + RepeatSubscriber.prototype.complete = function () { + if (!this.isStopped) { + var _a = this, source = _a.source, count = _a.count; + if (count === 0) { + return _super.prototype.complete.call(this); + } + else if (count > -1) { + this.count = count - 1; + } + source.subscribe(this._unsubscribeAndRecycle()); + } }; - return IgnoreElementsSubscriber; + return RepeatSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=ignoreElements.js.map +//# sourceMappingURL=repeat.js.map /***/ }), -/* 429 */ +/* 463 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return isEmpty; }); +/* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_Subject,_innerSubscribe PURE_IMPORTS_END */ -function isEmpty() { - return function (source) { return source.lift(new IsEmptyOperator()); }; + +function repeatWhen(notifier) { + return function (source) { return source.lift(new RepeatWhenOperator(notifier)); }; } -var IsEmptyOperator = /*@__PURE__*/ (function () { - function IsEmptyOperator() { +var RepeatWhenOperator = /*@__PURE__*/ (function () { + function RepeatWhenOperator(notifier) { + this.notifier = notifier; } - IsEmptyOperator.prototype.call = function (observer, source) { - return source.subscribe(new IsEmptySubscriber(observer)); + RepeatWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RepeatWhenSubscriber(subscriber, this.notifier, source)); }; - return IsEmptyOperator; + return RepeatWhenOperator; }()); -var IsEmptySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](IsEmptySubscriber, _super); - function IsEmptySubscriber(destination) { - return _super.call(this, destination) || this; +var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RepeatWhenSubscriber, _super); + function RepeatWhenSubscriber(destination, notifier, source) { + var _this = _super.call(this, destination) || this; + _this.notifier = notifier; + _this.source = source; + _this.sourceIsBeingSubscribedTo = true; + return _this; } - IsEmptySubscriber.prototype.notifyComplete = function (isEmpty) { - var destination = this.destination; - destination.next(isEmpty); - destination.complete(); + RepeatWhenSubscriber.prototype.notifyNext = function () { + this.sourceIsBeingSubscribedTo = true; + this.source.subscribe(this); }; - IsEmptySubscriber.prototype._next = function (value) { - this.notifyComplete(false); + RepeatWhenSubscriber.prototype.notifyComplete = function () { + if (this.sourceIsBeingSubscribedTo === false) { + return _super.prototype.complete.call(this); + } }; - IsEmptySubscriber.prototype._complete = function () { - this.notifyComplete(true); + RepeatWhenSubscriber.prototype.complete = function () { + this.sourceIsBeingSubscribedTo = false; + if (!this.isStopped) { + if (!this.retries) { + this.subscribeToRetries(); + } + if (!this.retriesSubscription || this.retriesSubscription.closed) { + return _super.prototype.complete.call(this); + } + this._unsubscribeAndRecycle(); + this.notifications.next(undefined); + } }; - return IsEmptySubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=isEmpty.js.map - - -/***/ }), -/* 430 */ -/***/ (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__(431); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(417); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(408); -/* 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 */ - - - - - - -function last(predicate, defaultValue) { - var hasDefaultValue = arguments.length >= 2; - return function (source) { return source.pipe(predicate ? Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(function (v, i) { return predicate(v, i, source); }) : _util_identity__WEBPACK_IMPORTED_MODULE_5__["identity"], Object(_takeLast__WEBPACK_IMPORTED_MODULE_2__["takeLast"])(1), hasDefaultValue ? Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__["defaultIfEmpty"])(defaultValue) : Object(_throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__["throwIfEmpty"])(function () { return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__["EmptyError"](); })); }; -} -//# sourceMappingURL=last.js.map + RepeatWhenSubscriber.prototype._unsubscribe = function () { + var _a = this, notifications = _a.notifications, retriesSubscription = _a.retriesSubscription; + if (notifications) { + notifications.unsubscribe(); + this.notifications = undefined; + } + if (retriesSubscription) { + retriesSubscription.unsubscribe(); + this.retriesSubscription = undefined; + } + this.retries = undefined; + }; + RepeatWhenSubscriber.prototype._unsubscribeAndRecycle = function () { + var _unsubscribe = this._unsubscribe; + this._unsubscribe = null; + _super.prototype._unsubscribeAndRecycle.call(this); + this._unsubscribe = _unsubscribe; + return this; + }; + RepeatWhenSubscriber.prototype.subscribeToRetries = function () { + this.notifications = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + var retries; + try { + var notifier = this.notifier; + retries = notifier(this.notifications); + } + catch (e) { + return _super.prototype.complete.call(this); + } + this.retries = retries; + this.retriesSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["innerSubscribe"])(retries, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleInnerSubscriber"](this)); + }; + return RepeatWhenSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleOuterSubscriber"])); +//# sourceMappingURL=repeatWhen.js.map /***/ }), -/* 431 */ +/* 464 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return takeLast; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return retry; }); /* 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 _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(62); -/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(43); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError,_observable_empty PURE_IMPORTS_END */ - - +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function takeLast(count) { - return function takeLastOperatorFunction(source) { - if (count === 0) { - return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_3__["empty"])(); - } - else { - return source.lift(new TakeLastOperator(count)); - } - }; +function retry(count) { + if (count === void 0) { + count = -1; + } + return function (source) { return source.lift(new RetryOperator(count, source)); }; } -var TakeLastOperator = /*@__PURE__*/ (function () { - function TakeLastOperator(total) { - this.total = total; - if (this.total < 0) { - throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; - } +var RetryOperator = /*@__PURE__*/ (function () { + function RetryOperator(count, source) { + this.count = count; + this.source = source; } - TakeLastOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TakeLastSubscriber(subscriber, this.total)); + RetryOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RetrySubscriber(subscriber, this.count, this.source)); }; - return TakeLastOperator; + return RetryOperator; }()); -var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeLastSubscriber, _super); - function TakeLastSubscriber(destination, total) { +var RetrySubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RetrySubscriber, _super); + function RetrySubscriber(destination, count, source) { var _this = _super.call(this, destination) || this; - _this.total = total; - _this.ring = new Array(); - _this.count = 0; + _this.count = count; + _this.source = source; return _this; } - TakeLastSubscriber.prototype._next = function (value) { - var ring = this.ring; - var total = this.total; - var count = this.count++; - if (ring.length < total) { - ring.push(value); - } - else { - var index = count % total; - ring[index] = value; - } - }; - TakeLastSubscriber.prototype._complete = function () { - var destination = this.destination; - var count = this.count; - if (count > 0) { - var total = this.count >= this.total ? this.total : this.count; - var ring = this.ring; - for (var i = 0; i < total; i++) { - var idx = (count++) % total; - destination.next(ring[idx]); + RetrySubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var _a = this, source = _a.source, count = _a.count; + if (count === 0) { + return _super.prototype.error.call(this, err); + } + else if (count > -1) { + this.count = count - 1; } + source.subscribe(this._unsubscribeAndRecycle()); } - destination.complete(); }; - return TakeLastSubscriber; + return RetrySubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=takeLast.js.map +//# sourceMappingURL=retry.js.map /***/ }), -/* 432 */ +/* 465 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return mapTo; }); +/* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_Subject,_innerSubscribe PURE_IMPORTS_END */ -function mapTo(value) { - return function (source) { return source.lift(new MapToOperator(value)); }; + +function retryWhen(notifier) { + return function (source) { return source.lift(new RetryWhenOperator(notifier, source)); }; } -var MapToOperator = /*@__PURE__*/ (function () { - function MapToOperator(value) { - this.value = value; +var RetryWhenOperator = /*@__PURE__*/ (function () { + function RetryWhenOperator(notifier, source) { + this.notifier = notifier; + this.source = source; } - MapToOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new MapToSubscriber(subscriber, this.value)); + RetryWhenOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new RetryWhenSubscriber(subscriber, this.notifier, this.source)); }; - return MapToOperator; + return RetryWhenOperator; }()); -var MapToSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MapToSubscriber, _super); - function MapToSubscriber(destination, value) { +var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RetryWhenSubscriber, _super); + function RetryWhenSubscriber(destination, notifier, source) { var _this = _super.call(this, destination) || this; - _this.value = value; + _this.notifier = notifier; + _this.source = source; return _this; } - MapToSubscriber.prototype._next = function (x) { - this.destination.next(this.value); + RetryWhenSubscriber.prototype.error = function (err) { + if (!this.isStopped) { + var errors = this.errors; + var retries = this.retries; + var retriesSubscription = this.retriesSubscription; + if (!retries) { + errors = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + try { + var notifier = this.notifier; + retries = notifier(errors); + } + catch (e) { + return _super.prototype.error.call(this, e); + } + retriesSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["innerSubscribe"])(retries, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleInnerSubscriber"](this)); + } + else { + this.errors = undefined; + this.retriesSubscription = undefined; + } + this._unsubscribeAndRecycle(); + this.errors = errors; + this.retries = retries; + this.retriesSubscription = retriesSubscription; + errors.next(err); + } + }; + RetryWhenSubscriber.prototype._unsubscribe = function () { + var _a = this, errors = _a.errors, retriesSubscription = _a.retriesSubscription; + if (errors) { + errors.unsubscribe(); + this.errors = undefined; + } + if (retriesSubscription) { + retriesSubscription.unsubscribe(); + this.retriesSubscription = undefined; + } + this.retries = undefined; }; - return MapToSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=mapTo.js.map + RetryWhenSubscriber.prototype.notifyNext = function () { + var _unsubscribe = this._unsubscribe; + this._unsubscribe = null; + this._unsubscribeAndRecycle(); + this._unsubscribe = _unsubscribe; + this.source.subscribe(this); + }; + return RetryWhenSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleOuterSubscriber"])); +//# sourceMappingURL=retryWhen.js.map /***/ }), -/* 433 */ +/* 466 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return materialize; }); +/* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(42); -/** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ - +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ -function materialize() { - return function materializeOperatorFunction(source) { - return source.lift(new MaterializeOperator()); - }; +function sample(notifier) { + return function (source) { return source.lift(new SampleOperator(notifier)); }; } -var MaterializeOperator = /*@__PURE__*/ (function () { - function MaterializeOperator() { +var SampleOperator = /*@__PURE__*/ (function () { + function SampleOperator(notifier) { + this.notifier = notifier; } - MaterializeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new MaterializeSubscriber(subscriber)); + SampleOperator.prototype.call = function (subscriber, source) { + var sampleSubscriber = new SampleSubscriber(subscriber); + var subscription = source.subscribe(sampleSubscriber); + subscription.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(this.notifier, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](sampleSubscriber))); + return subscription; }; - return MaterializeOperator; + return SampleOperator; }()); -var MaterializeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MaterializeSubscriber, _super); - function MaterializeSubscriber(destination) { - return _super.call(this, destination) || this; +var SampleSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SampleSubscriber, _super); + function SampleSubscriber() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.hasValue = false; + return _this; } - MaterializeSubscriber.prototype._next = function (value) { - this.destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createNext(value)); + SampleSubscriber.prototype._next = function (value) { + this.value = value; + this.hasValue = true; }; - MaterializeSubscriber.prototype._error = function (err) { - var destination = this.destination; - destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createError(err)); - destination.complete(); + SampleSubscriber.prototype.notifyNext = function () { + this.emitValue(); }; - MaterializeSubscriber.prototype._complete = function () { - var destination = this.destination; - destination.next(_Notification__WEBPACK_IMPORTED_MODULE_2__["Notification"].createComplete()); - destination.complete(); + SampleSubscriber.prototype.notifyComplete = function () { + this.emitValue(); }; - return MaterializeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=materialize.js.map - - -/***/ }), -/* 434 */ -/***/ (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__(435); -/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ - -function max(comparer) { - var max = (typeof comparer === 'function') - ? function (x, y) { return comparer(x, y) > 0 ? x : y; } - : function (x, y) { return x > y ? x : y; }; - return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(max); -} -//# sourceMappingURL=max.js.map + SampleSubscriber.prototype.emitValue = function () { + if (this.hasValue) { + this.hasValue = false; + this.destination.next(this.value); + } + }; + return SampleSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); +//# sourceMappingURL=sample.js.map /***/ }), -/* 435 */ +/* 467 */ /***/ (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__(436); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(431); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(408); -/* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(24); -/** PURE_IMPORTS_START _scan,_takeLast,_defaultIfEmpty,_util_pipe PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return sampleTime; }); +/* 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); +/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async PURE_IMPORTS_END */ -function reduce(accumulator, seed) { - if (arguments.length >= 2) { - return function reduceOperatorFunctionWithSeed(source) { - return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipe"])(Object(_scan__WEBPACK_IMPORTED_MODULE_0__["scan"])(accumulator, seed), Object(_takeLast__WEBPACK_IMPORTED_MODULE_1__["takeLast"])(1), Object(_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__["defaultIfEmpty"])(seed))(source); - }; +function sampleTime(period, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; } - return function reduceOperatorFunction(source) { - return Object(_util_pipe__WEBPACK_IMPORTED_MODULE_3__["pipe"])(Object(_scan__WEBPACK_IMPORTED_MODULE_0__["scan"])(function (acc, value, index) { return accumulator(acc, value, index + 1); }), Object(_takeLast__WEBPACK_IMPORTED_MODULE_1__["takeLast"])(1))(source); + return function (source) { return source.lift(new SampleTimeOperator(period, scheduler)); }; +} +var SampleTimeOperator = /*@__PURE__*/ (function () { + function SampleTimeOperator(period, scheduler) { + this.period = period; + this.scheduler = scheduler; + } + SampleTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SampleTimeSubscriber(subscriber, this.period, this.scheduler)); + }; + return SampleTimeOperator; +}()); +var SampleTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SampleTimeSubscriber, _super); + function SampleTimeSubscriber(destination, period, scheduler) { + var _this = _super.call(this, destination) || this; + _this.period = period; + _this.scheduler = scheduler; + _this.hasValue = false; + _this.add(scheduler.schedule(dispatchNotification, period, { subscriber: _this, period: period })); + return _this; + } + SampleTimeSubscriber.prototype._next = function (value) { + this.lastValue = value; + this.hasValue = true; + }; + SampleTimeSubscriber.prototype.notifyNext = function () { + if (this.hasValue) { + this.hasValue = false; + this.destination.next(this.lastValue); + } }; + return SampleTimeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +function dispatchNotification(state) { + var subscriber = state.subscriber, period = state.period; + subscriber.notifyNext(); + this.schedule(state, period); } -//# sourceMappingURL=reduce.js.map +//# sourceMappingURL=sampleTime.js.map /***/ }), -/* 436 */ +/* 468 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return scan; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return sequenceEqual; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SequenceEqualOperator", function() { return SequenceEqualOperator; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SequenceEqualSubscriber", function() { return SequenceEqualSubscriber; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function scan(accumulator, seed) { - var hasSeed = false; - if (arguments.length >= 2) { - hasSeed = true; - } - return function scanOperatorFunction(source) { - return source.lift(new ScanOperator(accumulator, seed, hasSeed)); - }; +function sequenceEqual(compareTo, comparator) { + return function (source) { return source.lift(new SequenceEqualOperator(compareTo, comparator)); }; } -var ScanOperator = /*@__PURE__*/ (function () { - function ScanOperator(accumulator, seed, hasSeed) { - if (hasSeed === void 0) { - hasSeed = false; - } - this.accumulator = accumulator; - this.seed = seed; - this.hasSeed = hasSeed; +var SequenceEqualOperator = /*@__PURE__*/ (function () { + function SequenceEqualOperator(compareTo, comparator) { + this.compareTo = compareTo; + this.comparator = comparator; } - ScanOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ScanSubscriber(subscriber, this.accumulator, this.seed, this.hasSeed)); + SequenceEqualOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SequenceEqualSubscriber(subscriber, this.compareTo, this.comparator)); }; - return ScanOperator; + return SequenceEqualOperator; }()); -var ScanSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ScanSubscriber, _super); - function ScanSubscriber(destination, accumulator, _seed, hasSeed) { + +var SequenceEqualSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SequenceEqualSubscriber, _super); + function SequenceEqualSubscriber(destination, compareTo, comparator) { var _this = _super.call(this, destination) || this; - _this.accumulator = accumulator; - _this._seed = _seed; - _this.hasSeed = hasSeed; - _this.index = 0; + _this.compareTo = compareTo; + _this.comparator = comparator; + _this._a = []; + _this._b = []; + _this._oneComplete = false; + _this.destination.add(compareTo.subscribe(new SequenceEqualCompareToSubscriber(destination, _this))); return _this; } - Object.defineProperty(ScanSubscriber.prototype, "seed", { - get: function () { - return this._seed; - }, - set: function (value) { - this.hasSeed = true; - this._seed = value; - }, - enumerable: true, - configurable: true - }); - ScanSubscriber.prototype._next = function (value) { - if (!this.hasSeed) { - this.seed = value; - this.destination.next(value); + SequenceEqualSubscriber.prototype._next = function (value) { + if (this._oneComplete && this._b.length === 0) { + this.emit(false); } else { - return this._tryNext(value); + this._a.push(value); + this.checkValues(); } }; - ScanSubscriber.prototype._tryNext = function (value) { - var index = this.index++; - var result; - try { - result = this.accumulator(this.seed, value, index); + SequenceEqualSubscriber.prototype._complete = function () { + if (this._oneComplete) { + this.emit(this._a.length === 0 && this._b.length === 0); } - catch (err) { - this.destination.error(err); + else { + this._oneComplete = true; } - this.seed = result; - this.destination.next(result); + this.unsubscribe(); }; - return ScanSubscriber; + SequenceEqualSubscriber.prototype.checkValues = function () { + var _c = this, _a = _c._a, _b = _c._b, comparator = _c.comparator; + while (_a.length > 0 && _b.length > 0) { + var a = _a.shift(); + var b = _b.shift(); + var areEqual = false; + try { + areEqual = comparator ? comparator(a, b) : a === b; + } + catch (e) { + this.destination.error(e); + } + if (!areEqual) { + this.emit(false); + } + } + }; + SequenceEqualSubscriber.prototype.emit = function (value) { + var destination = this.destination; + destination.next(value); + destination.complete(); + }; + SequenceEqualSubscriber.prototype.nextB = function (value) { + if (this._oneComplete && this._a.length === 0) { + this.emit(false); + } + else { + this._b.push(value); + this.checkValues(); + } + }; + SequenceEqualSubscriber.prototype.completeB = function () { + if (this._oneComplete) { + this.emit(this._a.length === 0 && this._b.length === 0); + } + else { + this._oneComplete = true; + } + }; + return SequenceEqualSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=scan.js.map + +var SequenceEqualCompareToSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SequenceEqualCompareToSubscriber, _super); + function SequenceEqualCompareToSubscriber(destination, parent) { + var _this = _super.call(this, destination) || this; + _this.parent = parent; + return _this; + } + SequenceEqualCompareToSubscriber.prototype._next = function (value) { + this.parent.nextB(value); + }; + SequenceEqualCompareToSubscriber.prototype._error = function (err) { + this.parent.error(err); + this.unsubscribe(); + }; + SequenceEqualCompareToSubscriber.prototype._complete = function () { + this.parent.completeB(); + this.unsubscribe(); + }; + return SequenceEqualCompareToSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=sequenceEqual.js.map /***/ }), -/* 437 */ +/* 469 */ /***/ (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); -/** PURE_IMPORTS_START _observable_merge PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "share", function() { return share; }); +/* 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 */ -function merge() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - return function (source) { return source.lift.call(_observable_merge__WEBPACK_IMPORTED_MODULE_0__["merge"].apply(void 0, [source].concat(observables))); }; + + +function shareSubjectFactory() { + return new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"](); } -//# sourceMappingURL=merge.js.map +function share() { + return function (source) { return Object(_refCount__WEBPACK_IMPORTED_MODULE_1__["refCount"])()(Object(_multicast__WEBPACK_IMPORTED_MODULE_0__["multicast"])(shareSubjectFactory)(source)); }; +} +//# sourceMappingURL=share.js.map /***/ }), -/* 438 */ +/* 470 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return mergeMapTo; }); -/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(82); -/** PURE_IMPORTS_START _mergeMap PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return shareReplay; }); +/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33); +/** PURE_IMPORTS_START _ReplaySubject PURE_IMPORTS_END */ -function mergeMapTo(innerObservable, resultSelector, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - if (typeof resultSelector === 'function') { - return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(function () { return innerObservable; }, resultSelector, concurrent); +function shareReplay(configOrBufferSize, windowTime, scheduler) { + var config; + if (configOrBufferSize && typeof configOrBufferSize === 'object') { + config = configOrBufferSize; } - if (typeof resultSelector === 'number') { - concurrent = resultSelector; + else { + config = { + bufferSize: configOrBufferSize, + windowTime: windowTime, + refCount: false, + scheduler: scheduler + }; } - return Object(_mergeMap__WEBPACK_IMPORTED_MODULE_0__["mergeMap"])(function () { return innerObservable; }, concurrent); + return function (source) { return source.lift(shareReplayOperator(config)); }; } -//# sourceMappingURL=mergeMapTo.js.map +function shareReplayOperator(_a) { + var _b = _a.bufferSize, bufferSize = _b === void 0 ? Number.POSITIVE_INFINITY : _b, _c = _a.windowTime, windowTime = _c === void 0 ? Number.POSITIVE_INFINITY : _c, useRefCount = _a.refCount, scheduler = _a.scheduler; + var subject; + var refCount = 0; + var subscription; + var hasError = false; + 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) { + hasError = true; + subject.error(err); + }, + complete: function () { + isComplete = true; + subscription = undefined; + subject.complete(); + }, + }); + } + else { + innerSub = subject.subscribe(this); + } + this.add(function () { + refCount--; + innerSub.unsubscribe(); + if (subscription && !isComplete && useRefCount && refCount === 0) { + subscription.unsubscribe(); + subscription = undefined; + subject = undefined; + } + }); + }; +} +//# sourceMappingURL=shareReplay.js.map /***/ }), -/* 439 */ +/* 471 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return mergeScan; }); -/* 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 export (binding) */ __webpack_require__.d(__webpack_exports__, "single", function() { return single; }); /* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(63); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_EmptyError PURE_IMPORTS_END */ -function mergeScan(accumulator, seed, concurrent) { - if (concurrent === void 0) { - concurrent = Number.POSITIVE_INFINITY; - } - return function (source) { return source.lift(new MergeScanOperator(accumulator, seed, concurrent)); }; +function single(predicate) { + return function (source) { return source.lift(new SingleOperator(predicate, source)); }; } -var MergeScanOperator = /*@__PURE__*/ (function () { - function MergeScanOperator(accumulator, seed, concurrent) { - this.accumulator = accumulator; - this.seed = seed; - this.concurrent = concurrent; +var SingleOperator = /*@__PURE__*/ (function () { + function SingleOperator(predicate, source) { + this.predicate = predicate; + this.source = source; } - MergeScanOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new MergeScanSubscriber(subscriber, this.accumulator, this.seed, this.concurrent)); + SingleOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SingleSubscriber(subscriber, this.predicate, this.source)); }; - return MergeScanOperator; + return SingleOperator; }()); - -var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](MergeScanSubscriber, _super); - function MergeScanSubscriber(destination, accumulator, acc, concurrent) { +var SingleSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SingleSubscriber, _super); + function SingleSubscriber(destination, predicate, source) { var _this = _super.call(this, destination) || this; - _this.accumulator = accumulator; - _this.acc = acc; - _this.concurrent = concurrent; - _this.hasValue = false; - _this.hasCompleted = false; - _this.buffer = []; - _this.active = 0; + _this.predicate = predicate; + _this.source = source; + _this.seenValue = false; _this.index = 0; return _this; } - MergeScanSubscriber.prototype._next = function (value) { - if (this.active < this.concurrent) { - var index = this.index++; - var destination = this.destination; - var ish = void 0; - try { - var accumulator = this.accumulator; - ish = accumulator(this.acc, value, index); - } - catch (e) { - return destination.error(e); - } - this.active++; - this._innerSub(ish, value, index); + SingleSubscriber.prototype.applySingleValue = function (value) { + if (this.seenValue) { + this.destination.error('Sequence contains more than one element'); } else { - this.buffer.push(value); + this.seenValue = true; + this.singleValue = value; } }; - MergeScanSubscriber.prototype._innerSub = function (ish, value, index) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_3__["InnerSubscriber"](this, value, index); - var destination = this.destination; - destination.add(innerSubscriber); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_1__["subscribeToResult"])(this, ish, undefined, undefined, innerSubscriber); - if (innerSubscription !== innerSubscriber) { - destination.add(innerSubscription); + SingleSubscriber.prototype._next = function (value) { + var index = this.index++; + if (this.predicate) { + this.tryNext(value, index); + } + else { + this.applySingleValue(value); } }; - MergeScanSubscriber.prototype._complete = function () { - this.hasCompleted = true; - if (this.active === 0 && this.buffer.length === 0) { - if (this.hasValue === false) { - this.destination.next(this.acc); + SingleSubscriber.prototype.tryNext = function (value, index) { + try { + if (this.predicate(value, index, this.source)) { + this.applySingleValue(value); } - this.destination.complete(); } - this.unsubscribe(); - }; - MergeScanSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - var destination = this.destination; - this.acc = innerValue; - this.hasValue = true; - destination.next(innerValue); + catch (err) { + this.destination.error(err); + } }; - MergeScanSubscriber.prototype.notifyComplete = function (innerSub) { - var buffer = this.buffer; + SingleSubscriber.prototype._complete = function () { var destination = this.destination; - destination.remove(innerSub); - this.active--; - if (buffer.length > 0) { - this._next(buffer.shift()); + if (this.index > 0) { + destination.next(this.seenValue ? this.singleValue : undefined); + destination.complete(); } - else if (this.active === 0 && this.hasCompleted) { - if (this.hasValue === false) { - this.destination.next(this.acc); - } - this.destination.complete(); + else { + destination.error(new _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__["EmptyError"]); } }; - return MergeScanSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); - -//# sourceMappingURL=mergeScan.js.map + return SingleSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=single.js.map /***/ }), -/* 440 */ +/* 472 */ /***/ (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__(435); -/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return skip; }); +/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); +/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function min(comparer) { - var min = (typeof comparer === 'function') - ? function (x, y) { return comparer(x, y) < 0 ? x : y; } - : function (x, y) { return x < y ? x : y; }; - return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(min); + +function skip(count) { + return function (source) { return source.lift(new SkipOperator(count)); }; } -//# sourceMappingURL=min.js.map +var SkipOperator = /*@__PURE__*/ (function () { + function SkipOperator(total) { + this.total = total; + } + SkipOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SkipSubscriber(subscriber, this.total)); + }; + return SkipOperator; +}()); +var SkipSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipSubscriber, _super); + function SkipSubscriber(destination, total) { + var _this = _super.call(this, destination) || this; + _this.total = total; + _this.count = 0; + return _this; + } + SkipSubscriber.prototype._next = function (x) { + if (++this.count > this.total) { + this.destination.next(x); + } + }; + return SkipSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=skip.js.map /***/ }), -/* 441 */ +/* 473 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return multicast; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MulticastOperator", function() { return MulticastOperator; }); -/* harmony import */ var _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26); -/** PURE_IMPORTS_START _observable_ConnectableObservable PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return skipLast; }); +/* 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 _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(62); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError PURE_IMPORTS_END */ -function multicast(subjectOrSubjectFactory, selector) { - return function multicastOperatorFunction(source) { - var subjectFactory; - if (typeof subjectOrSubjectFactory === 'function') { - subjectFactory = subjectOrSubjectFactory; + + +function skipLast(count) { + return function (source) { return source.lift(new SkipLastOperator(count)); }; +} +var SkipLastOperator = /*@__PURE__*/ (function () { + function SkipLastOperator(_skipCount) { + this._skipCount = _skipCount; + if (this._skipCount < 0) { + throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; } - else { - subjectFactory = function subjectFactory() { - return subjectOrSubjectFactory; - }; + } + SkipLastOperator.prototype.call = function (subscriber, source) { + if (this._skipCount === 0) { + return source.subscribe(new _Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"](subscriber)); } - if (typeof selector === 'function') { - return source.lift(new MulticastOperator(subjectFactory, selector)); + else { + return source.subscribe(new SkipLastSubscriber(subscriber, this._skipCount)); } - var connectable = Object.create(source, _observable_ConnectableObservable__WEBPACK_IMPORTED_MODULE_0__["connectableObservableDescriptor"]); - connectable.source = source; - connectable.subjectFactory = subjectFactory; - return connectable; }; -} -var MulticastOperator = /*@__PURE__*/ (function () { - function MulticastOperator(subjectFactory, selector) { - this.subjectFactory = subjectFactory; - this.selector = selector; + return SkipLastOperator; +}()); +var SkipLastSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipLastSubscriber, _super); + function SkipLastSubscriber(destination, _skipCount) { + var _this = _super.call(this, destination) || this; + _this._skipCount = _skipCount; + _this._count = 0; + _this._ring = new Array(_skipCount); + return _this; } - MulticastOperator.prototype.call = function (subscriber, source) { - var selector = this.selector; - var subject = this.subjectFactory(); - var subscription = selector(subject).subscribe(subscriber); - subscription.add(source.subscribe(subject)); - return subscription; + SkipLastSubscriber.prototype._next = function (value) { + var skipCount = this._skipCount; + var count = this._count++; + if (count < skipCount) { + this._ring[count] = value; + } + else { + var currentIndex = count % skipCount; + var ring = this._ring; + var oldValue = ring[currentIndex]; + ring[currentIndex] = value; + this.destination.next(oldValue); + } }; - return MulticastOperator; -}()); - -//# sourceMappingURL=multicast.js.map + return SkipLastSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=skipLast.js.map /***/ }), -/* 442 */ +/* 474 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return onErrorResumeNext; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNextStatic", function() { return onErrorResumeNextStatic; }); +/* 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 _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_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ - -function onErrorResumeNext() { - var nextSources = []; - for (var _i = 0; _i < arguments.length; _i++) { - nextSources[_i] = arguments[_i]; - } - if (nextSources.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_2__["isArray"])(nextSources[0])) { - nextSources = nextSources[0]; - } - return function (source) { return source.lift(new OnErrorResumeNextOperator(nextSources)); }; -} -function onErrorResumeNextStatic() { - var nextSources = []; - for (var _i = 0; _i < arguments.length; _i++) { - nextSources[_i] = arguments[_i]; - } - var source = null; - 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)); +function skipUntil(notifier) { + return function (source) { return source.lift(new SkipUntilOperator(notifier)); }; } -var OnErrorResumeNextOperator = /*@__PURE__*/ (function () { - function OnErrorResumeNextOperator(nextSources) { - this.nextSources = nextSources; +var SkipUntilOperator = /*@__PURE__*/ (function () { + function SkipUntilOperator(notifier) { + this.notifier = notifier; } - OnErrorResumeNextOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new OnErrorResumeNextSubscriber(subscriber, this.nextSources)); + SkipUntilOperator.prototype.call = function (destination, source) { + return source.subscribe(new SkipUntilSubscriber(destination, this.notifier)); }; - return OnErrorResumeNextOperator; + return SkipUntilOperator; }()); -var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](OnErrorResumeNextSubscriber, _super); - function OnErrorResumeNextSubscriber(destination, nextSources) { +var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipUntilSubscriber, _super); + function SkipUntilSubscriber(destination, notifier) { var _this = _super.call(this, destination) || this; - _this.destination = destination; - _this.nextSources = nextSources; + _this.hasValue = false; + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](_this); + _this.add(innerSubscriber); + _this.innerSubscription = innerSubscriber; + var innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(notifier, innerSubscriber); + if (innerSubscription !== innerSubscriber) { + _this.add(innerSubscription); + _this.innerSubscription = innerSubscription; + } return _this; } - OnErrorResumeNextSubscriber.prototype.notifyError = function (error, innerSub) { - this.subscribeToNextSource(); - }; - OnErrorResumeNextSubscriber.prototype.notifyComplete = function (innerSub) { - this.subscribeToNextSource(); - }; - OnErrorResumeNextSubscriber.prototype._error = function (err) { - this.subscribeToNextSource(); - this.unsubscribe(); - }; - OnErrorResumeNextSubscriber.prototype._complete = function () { - this.subscribeToNextSource(); - this.unsubscribe(); - }; - OnErrorResumeNextSubscriber.prototype.subscribeToNextSource = function () { - var next = this.nextSources.shift(); - if (!!next) { - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_4__["InnerSubscriber"](this, undefined, undefined); - var destination = this.destination; - destination.add(innerSubscriber); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_5__["subscribeToResult"])(this, next, undefined, undefined, innerSubscriber); - if (innerSubscription !== innerSubscriber) { - destination.add(innerSubscription); - } + SkipUntilSubscriber.prototype._next = function (value) { + if (this.hasValue) { + _super.prototype._next.call(this, value); } - else { - this.destination.complete(); + }; + SkipUntilSubscriber.prototype.notifyNext = function () { + this.hasValue = true; + if (this.innerSubscription) { + this.innerSubscription.unsubscribe(); } }; - return OnErrorResumeNextSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -//# sourceMappingURL=onErrorResumeNext.js.map + SkipUntilSubscriber.prototype.notifyComplete = function () { + }; + return SkipUntilSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); +//# sourceMappingURL=skipUntil.js.map /***/ }), -/* 443 */ +/* 475 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return pairwise; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return skipWhile; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); /** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function pairwise() { - return function (source) { return source.lift(new PairwiseOperator()); }; +function skipWhile(predicate) { + return function (source) { return source.lift(new SkipWhileOperator(predicate)); }; } -var PairwiseOperator = /*@__PURE__*/ (function () { - function PairwiseOperator() { +var SkipWhileOperator = /*@__PURE__*/ (function () { + function SkipWhileOperator(predicate) { + this.predicate = predicate; } - PairwiseOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new PairwiseSubscriber(subscriber)); + SkipWhileOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SkipWhileSubscriber(subscriber, this.predicate)); }; - return PairwiseOperator; + return SkipWhileOperator; }()); -var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](PairwiseSubscriber, _super); - function PairwiseSubscriber(destination) { +var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipWhileSubscriber, _super); + function SkipWhileSubscriber(destination, predicate) { var _this = _super.call(this, destination) || this; - _this.hasPrev = false; + _this.predicate = predicate; + _this.skipping = true; + _this.index = 0; return _this; } - PairwiseSubscriber.prototype._next = function (value) { - var pair; - if (this.hasPrev) { - pair = [this.prev, value]; + SkipWhileSubscriber.prototype._next = function (value) { + var destination = this.destination; + if (this.skipping) { + this.tryCallPredicate(value); } - else { - this.hasPrev = true; + if (!this.skipping) { + destination.next(value); } - this.prev = value; - if (pair) { - this.destination.next(pair); + }; + SkipWhileSubscriber.prototype.tryCallPredicate = function (value) { + try { + var result = this.predicate(value, this.index++); + this.skipping = Boolean(result); + } + catch (err) { + this.destination.error(err); } }; - return PairwiseSubscriber; + return SkipWhileSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=pairwise.js.map +//# sourceMappingURL=skipWhile.js.map /***/ }), -/* 444 */ +/* 476 */ /***/ (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); -/** PURE_IMPORTS_START _util_not,_filter PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return startWith; }); +/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(79); +/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45); +/** PURE_IMPORTS_START _observable_concat,_util_isScheduler PURE_IMPORTS_END */ -function partition(predicate, thisArg) { - return function (source) { - return [ - Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(predicate, thisArg)(source), - Object(_filter__WEBPACK_IMPORTED_MODULE_1__["filter"])(Object(_util_not__WEBPACK_IMPORTED_MODULE_0__["not"])(predicate, thisArg))(source) - ]; - }; +function startWith() { + var array = []; + for (var _i = 0; _i < arguments.length; _i++) { + array[_i] = arguments[_i]; + } + var scheduler = array[array.length - 1]; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__["isScheduler"])(scheduler)) { + array.pop(); + return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(array, source, scheduler); }; + } + else { + return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(array, source); }; + } } -//# sourceMappingURL=partition.js.map +//# sourceMappingURL=startWith.js.map /***/ }), -/* 445 */ +/* 477 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return pluck; }); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(66); -/** PURE_IMPORTS_START _map PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return subscribeOn; }); +/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(478); +/** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ -function pluck() { - var properties = []; - for (var _i = 0; _i < arguments.length; _i++) { - properties[_i] = arguments[_i]; - } - var length = properties.length; - if (length === 0) { - throw new Error('list of properties cannot be empty.'); +function subscribeOn(scheduler, delay) { + if (delay === void 0) { + delay = 0; } - return function (source) { return Object(_map__WEBPACK_IMPORTED_MODULE_0__["map"])(plucker(properties, length))(source); }; -} -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') { - currentProp = p; - } - else { - return undefined; - } - } - return currentProp; + return function subscribeOnOperatorFunction(source) { + return source.lift(new SubscribeOnOperator(scheduler, delay)); }; - return mapper; } -//# sourceMappingURL=pluck.js.map +var SubscribeOnOperator = /*@__PURE__*/ (function () { + function SubscribeOnOperator(scheduler, delay) { + this.scheduler = scheduler; + this.delay = delay; + } + SubscribeOnOperator.prototype.call = function (subscriber, source) { + return new _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__["SubscribeOnObservable"](source, this.delay, this.scheduler).subscribe(subscriber); + }; + return SubscribeOnOperator; +}()); +//# sourceMappingURL=subscribeOn.js.map /***/ }), -/* 446 */ +/* 478 */ /***/ (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__(441); -/** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubscribeOnObservable", function() { return SubscribeOnObservable; }); +/* 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__(98); +/** PURE_IMPORTS_START tslib,_Observable,_scheduler_asap,_util_isNumeric PURE_IMPORTS_END */ -function publish(selector) { - return selector ? - Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(function () { return new _Subject__WEBPACK_IMPORTED_MODULE_0__["Subject"](); }, selector) : - Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _Subject__WEBPACK_IMPORTED_MODULE_0__["Subject"]()); -} -//# sourceMappingURL=publish.js.map + + +var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscribeOnObservable, _super); + function SubscribeOnObservable(source, delayTime, scheduler) { + if (delayTime === void 0) { + delayTime = 0; + } + if (scheduler === void 0) { + scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; + } + var _this = _super.call(this) || this; + _this.source = source; + _this.delayTime = delayTime; + _this.scheduler = scheduler; + if (!Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_3__["isNumeric"])(delayTime) || delayTime < 0) { + _this.delayTime = 0; + } + if (!scheduler || typeof scheduler.schedule !== 'function') { + _this.scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; + } + return _this; + } + SubscribeOnObservable.create = function (source, delay, scheduler) { + if (delay === void 0) { + delay = 0; + } + if (scheduler === void 0) { + scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; + } + return new SubscribeOnObservable(source, delay, scheduler); + }; + SubscribeOnObservable.dispatch = function (arg) { + var source = arg.source, subscriber = arg.subscriber; + return this.add(source.subscribe(subscriber)); + }; + SubscribeOnObservable.prototype._subscribe = function (subscriber) { + var delay = this.delayTime; + var source = this.source; + var scheduler = this.scheduler; + return scheduler.schedule(SubscribeOnObservable.dispatch, delay, { + source: source, subscriber: subscriber + }); + }; + return SubscribeOnObservable; +}(_Observable__WEBPACK_IMPORTED_MODULE_1__["Observable"])); + +//# sourceMappingURL=SubscribeOnObservable.js.map /***/ }), -/* 447 */ +/* 479 */ /***/ (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__(441); -/** PURE_IMPORTS_START _BehaviorSubject,_multicast PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return switchAll; }); +/* 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 */ -function publishBehavior(value) { - return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__["BehaviorSubject"](value))(source); }; +function switchAll() { + return Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(_util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"]); } -//# sourceMappingURL=publishBehavior.js.map +//# sourceMappingURL=switchAll.js.map /***/ }), -/* 448 */ +/* 480 */ /***/ (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__(441); -/** PURE_IMPORTS_START _AsyncSubject,_multicast PURE_IMPORTS_END */ +/* 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 _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 publishLast() { - return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(new _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__["AsyncSubject"]())(source); }; + + +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_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)); }; } -//# sourceMappingURL=publishLast.js.map +var SwitchMapOperator = /*@__PURE__*/ (function () { + function SwitchMapOperator(project) { + this.project = project; + } + SwitchMapOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new SwitchMapSubscriber(subscriber, this.project)); + }; + return SwitchMapOperator; +}()); +var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SwitchMapSubscriber, _super); + function SwitchMapSubscriber(destination, project) { + var _this = _super.call(this, destination) || this; + _this.project = project; + _this.index = 0; + return _this; + } + SwitchMapSubscriber.prototype._next = function (value) { + var result; + var index = this.index++; + try { + result = this.project(value, index); + } + catch (error) { + this.destination.error(error); + return; + } + this._innerSub(result); + }; + SwitchMapSubscriber.prototype._innerSub = function (result) { + var innerSubscription = this.innerSubscription; + if (innerSubscription) { + innerSubscription.unsubscribe(); + } + var innerSubscriber = new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleInnerSubscriber"](this); + var destination = this.destination; + destination.add(innerSubscriber); + this.innerSubscription = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["innerSubscribe"])(result, innerSubscriber); + if (this.innerSubscription !== innerSubscriber) { + destination.add(this.innerSubscription); + } + }; + SwitchMapSubscriber.prototype._complete = function () { + var innerSubscription = this.innerSubscription; + if (!innerSubscription || innerSubscription.closed) { + _super.prototype._complete.call(this); + } + this.unsubscribe(); + }; + SwitchMapSubscriber.prototype._unsubscribe = function () { + this.innerSubscription = undefined; + }; + SwitchMapSubscriber.prototype.notifyComplete = function () { + this.innerSubscription = undefined; + if (this.isStopped) { + _super.prototype._complete.call(this); + } + }; + SwitchMapSubscriber.prototype.notifyNext = function (innerValue) { + this.destination.next(innerValue); + }; + return SwitchMapSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleOuterSubscriber"])); +//# sourceMappingURL=switchMap.js.map /***/ }), -/* 449 */ +/* 481 */ /***/ (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__(441); -/** PURE_IMPORTS_START _ReplaySubject,_multicast PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return switchMapTo; }); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(480); +/** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ -function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) { - if (selectorOrScheduler && typeof selectorOrScheduler !== 'function') { - scheduler = selectorOrScheduler; - } - var selector = typeof selectorOrScheduler === 'function' ? selectorOrScheduler : undefined; - var subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__["ReplaySubject"](bufferSize, windowTime, scheduler); - return function (source) { return Object(_multicast__WEBPACK_IMPORTED_MODULE_1__["multicast"])(function () { return subject; }, selector)(source); }; +function switchMapTo(innerObservable, resultSelector) { + return resultSelector ? Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(function () { return innerObservable; }, resultSelector) : Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(function () { return innerObservable; }); } -//# sourceMappingURL=publishReplay.js.map +//# sourceMappingURL=switchMapTo.js.map /***/ }), -/* 450 */ +/* 482 */ /***/ (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); -/** PURE_IMPORTS_START _util_isArray,_observable_race PURE_IMPORTS_END */ +/* 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 _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ -function race() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; +function takeUntil(notifier) { + return function (source) { return source.lift(new TakeUntilOperator(notifier)); }; +} +var TakeUntilOperator = /*@__PURE__*/ (function () { + function TakeUntilOperator(notifier) { + this.notifier = notifier; } - return function raceOperatorFunction(source) { - if (observables.length === 1 && Object(_util_isArray__WEBPACK_IMPORTED_MODULE_0__["isArray"])(observables[0])) { - observables = observables[0]; + TakeUntilOperator.prototype.call = function (subscriber, source) { + var takeUntilSubscriber = new TakeUntilSubscriber(subscriber); + 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); } - return source.lift.call(_observable_race__WEBPACK_IMPORTED_MODULE_1__["race"].apply(void 0, [source].concat(observables))); + return takeUntilSubscriber; }; -} -//# sourceMappingURL=race.js.map + return TakeUntilOperator; +}()); +var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeUntilSubscriber, _super); + function TakeUntilSubscriber(destination) { + var _this = _super.call(this, destination) || this; + _this.seenValue = false; + return _this; + } + TakeUntilSubscriber.prototype.notifyNext = function () { + this.seenValue = true; + this.complete(); + }; + TakeUntilSubscriber.prototype.notifyComplete = function () { + }; + return TakeUntilSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); +//# sourceMappingURL=takeUntil.js.map /***/ }), -/* 451 */ +/* 483 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return repeat; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return takeWhile; }); /* 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_empty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(43); -/** PURE_IMPORTS_START tslib,_Subscriber,_observable_empty PURE_IMPORTS_END */ - +/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ -function repeat(count) { - if (count === void 0) { - count = -1; +function takeWhile(predicate, inclusive) { + if (inclusive === void 0) { + inclusive = false; } return function (source) { - if (count === 0) { - return Object(_observable_empty__WEBPACK_IMPORTED_MODULE_2__["empty"])(); - } - else if (count < 0) { - return source.lift(new RepeatOperator(-1, source)); - } - else { - return source.lift(new RepeatOperator(count - 1, source)); - } + return source.lift(new TakeWhileOperator(predicate, inclusive)); }; } -var RepeatOperator = /*@__PURE__*/ (function () { - function RepeatOperator(count, source) { - this.count = count; - this.source = source; +var TakeWhileOperator = /*@__PURE__*/ (function () { + function TakeWhileOperator(predicate, inclusive) { + this.predicate = predicate; + this.inclusive = inclusive; } - RepeatOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RepeatSubscriber(subscriber, this.count, this.source)); + TakeWhileOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TakeWhileSubscriber(subscriber, this.predicate, this.inclusive)); }; - return RepeatOperator; + return TakeWhileOperator; }()); -var RepeatSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RepeatSubscriber, _super); - function RepeatSubscriber(destination, count, source) { +var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeWhileSubscriber, _super); + function TakeWhileSubscriber(destination, predicate, inclusive) { var _this = _super.call(this, destination) || this; - _this.count = count; - _this.source = source; + _this.predicate = predicate; + _this.inclusive = inclusive; + _this.index = 0; return _this; } - RepeatSubscriber.prototype.complete = function () { - if (!this.isStopped) { - var _a = this, source = _a.source, count = _a.count; - if (count === 0) { - return _super.prototype.complete.call(this); - } - else if (count > -1) { - this.count = count - 1; + TakeWhileSubscriber.prototype._next = function (value) { + var destination = this.destination; + var result; + try { + result = this.predicate(value, this.index++); + } + catch (err) { + destination.error(err); + return; + } + this.nextOrComplete(value, result); + }; + TakeWhileSubscriber.prototype.nextOrComplete = function (value, predicateResult) { + var destination = this.destination; + if (Boolean(predicateResult)) { + destination.next(value); + } + else { + if (this.inclusive) { + destination.next(value); } - source.subscribe(this._unsubscribeAndRecycle()); + destination.complete(); } }; - return RepeatSubscriber; + return TakeWhileSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=repeat.js.map +//# sourceMappingURL=takeWhile.js.map /***/ }), -/* 452 */ +/* 484 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return repeatWhen; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return tap; }); /* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); +/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(60); +/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(13); +/** PURE_IMPORTS_START tslib,_Subscriber,_util_noop,_util_isFunction PURE_IMPORTS_END */ -function repeatWhen(notifier) { - return function (source) { return source.lift(new RepeatWhenOperator(notifier)); }; +function tap(nextOrObserver, error, complete) { + return function tapOperatorFunction(source) { + return source.lift(new DoOperator(nextOrObserver, error, complete)); + }; } -var RepeatWhenOperator = /*@__PURE__*/ (function () { - function RepeatWhenOperator(notifier) { - this.notifier = notifier; +var DoOperator = /*@__PURE__*/ (function () { + function DoOperator(nextOrObserver, error, complete) { + this.nextOrObserver = nextOrObserver; + this.error = error; + this.complete = complete; } - RepeatWhenOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RepeatWhenSubscriber(subscriber, this.notifier, source)); + DoOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TapSubscriber(subscriber, this.nextOrObserver, this.error, this.complete)); }; - return RepeatWhenOperator; + return DoOperator; }()); -var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RepeatWhenSubscriber, _super); - function RepeatWhenSubscriber(destination, notifier, source) { +var TapSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TapSubscriber, _super); + function TapSubscriber(destination, observerOrNext, error, complete) { var _this = _super.call(this, destination) || this; - _this.notifier = notifier; - _this.source = source; - _this.sourceIsBeingSubscribedTo = true; + _this._tapNext = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapError = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapComplete = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapError = error || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapComplete = complete || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_3__["isFunction"])(observerOrNext)) { + _this._context = _this; + _this._tapNext = observerOrNext; + } + else if (observerOrNext) { + _this._context = observerOrNext; + _this._tapNext = observerOrNext.next || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapError = observerOrNext.error || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + _this._tapComplete = observerOrNext.complete || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; + } return _this; } - RepeatWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.sourceIsBeingSubscribedTo = true; - this.source.subscribe(this); + TapSubscriber.prototype._next = function (value) { + try { + this._tapNext.call(this._context, value); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.next(value); }; - RepeatWhenSubscriber.prototype.notifyComplete = function (innerSub) { - if (this.sourceIsBeingSubscribedTo === false) { - return _super.prototype.complete.call(this); + TapSubscriber.prototype._error = function (err) { + try { + this._tapError.call(this._context, err); + } + catch (err) { + this.destination.error(err); + return; + } + this.destination.error(err); + }; + TapSubscriber.prototype._complete = function () { + try { + this._tapComplete.call(this._context); + } + catch (err) { + this.destination.error(err); + return; } + return this.destination.complete(); }; - RepeatWhenSubscriber.prototype.complete = function () { - this.sourceIsBeingSubscribedTo = false; - if (!this.isStopped) { - if (!this.retries) { - this.subscribeToRetries(); + return TapSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=tap.js.map + + +/***/ }), +/* 485 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__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 _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_innerSubscribe PURE_IMPORTS_END */ + + +var defaultThrottleConfig = { + leading: true, + trailing: false +}; +function throttle(durationSelector, config) { + if (config === void 0) { + config = defaultThrottleConfig; + } + return function (source) { return source.lift(new ThrottleOperator(durationSelector, !!config.leading, !!config.trailing)); }; +} +var ThrottleOperator = /*@__PURE__*/ (function () { + function ThrottleOperator(durationSelector, leading, trailing) { + this.durationSelector = durationSelector; + this.leading = leading; + this.trailing = trailing; + } + ThrottleOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ThrottleSubscriber(subscriber, this.durationSelector, this.leading, this.trailing)); + }; + return ThrottleOperator; +}()); +var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrottleSubscriber, _super); + function ThrottleSubscriber(destination, durationSelector, _leading, _trailing) { + var _this = _super.call(this, destination) || this; + _this.destination = destination; + _this.durationSelector = durationSelector; + _this._leading = _leading; + _this._trailing = _trailing; + _this._hasValue = false; + return _this; + } + ThrottleSubscriber.prototype._next = function (value) { + this._hasValue = true; + this._sendValue = value; + if (!this._throttled) { + if (this._leading) { + this.send(); } - if (!this.retriesSubscription || this.retriesSubscription.closed) { - return _super.prototype.complete.call(this); + else { + this.throttle(value); } - this._unsubscribeAndRecycle(); - this.notifications.next(); } }; - RepeatWhenSubscriber.prototype._unsubscribe = function () { - var _a = this, notifications = _a.notifications, retriesSubscription = _a.retriesSubscription; - if (notifications) { - notifications.unsubscribe(); - this.notifications = null; - } - if (retriesSubscription) { - retriesSubscription.unsubscribe(); - this.retriesSubscription = null; + ThrottleSubscriber.prototype.send = function () { + var _a = this, _hasValue = _a._hasValue, _sendValue = _a._sendValue; + if (_hasValue) { + this.destination.next(_sendValue); + this.throttle(_sendValue); } - this.retries = null; + this._hasValue = false; + this._sendValue = undefined; }; - RepeatWhenSubscriber.prototype._unsubscribeAndRecycle = function () { - var _unsubscribe = this._unsubscribe; - this._unsubscribe = null; - _super.prototype._unsubscribeAndRecycle.call(this); - this._unsubscribe = _unsubscribe; - return this; + ThrottleSubscriber.prototype.throttle = function (value) { + var duration = this.tryDurationSelector(value); + if (!!duration) { + this.add(this._throttled = Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["innerSubscribe"])(duration, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleInnerSubscriber"](this))); + } }; - RepeatWhenSubscriber.prototype.subscribeToRetries = function () { - this.notifications = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - var retries; + ThrottleSubscriber.prototype.tryDurationSelector = function (value) { try { - var notifier = this.notifier; - retries = notifier(this.notifications); + return this.durationSelector(value); } - catch (e) { - return _super.prototype.complete.call(this); + catch (err) { + this.destination.error(err); + return null; } - this.retries = retries; - this.retriesSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, retries); }; - return RepeatWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=repeatWhen.js.map + ThrottleSubscriber.prototype.throttlingDone = function () { + var _a = this, _throttled = _a._throttled, _trailing = _a._trailing; + if (_throttled) { + _throttled.unsubscribe(); + } + this._throttled = undefined; + if (_trailing) { + this.send(); + } + }; + ThrottleSubscriber.prototype.notifyNext = function () { + this.throttlingDone(); + }; + ThrottleSubscriber.prototype.notifyComplete = function () { + this.throttlingDone(); + }; + return ThrottleSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_1__["SimpleOuterSubscriber"])); +//# sourceMappingURL=throttle.js.map /***/ }), -/* 453 */ +/* 486 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return retry; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return throttleTime; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55); +/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(485); +/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ -function retry(count) { - if (count === void 0) { - count = -1; + + +function throttleTime(duration, scheduler, config) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; } - return function (source) { return source.lift(new RetryOperator(count, source)); }; + if (config === void 0) { + config = _throttle__WEBPACK_IMPORTED_MODULE_3__["defaultThrottleConfig"]; + } + return function (source) { return source.lift(new ThrottleTimeOperator(duration, scheduler, config.leading, config.trailing)); }; } -var RetryOperator = /*@__PURE__*/ (function () { - function RetryOperator(count, source) { - this.count = count; - this.source = source; +var ThrottleTimeOperator = /*@__PURE__*/ (function () { + function ThrottleTimeOperator(duration, scheduler, leading, trailing) { + this.duration = duration; + this.scheduler = scheduler; + this.leading = leading; + this.trailing = trailing; } - RetryOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RetrySubscriber(subscriber, this.count, this.source)); + ThrottleTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new ThrottleTimeSubscriber(subscriber, this.duration, this.scheduler, this.leading, this.trailing)); }; - return RetryOperator; + return ThrottleTimeOperator; }()); -var RetrySubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RetrySubscriber, _super); - function RetrySubscriber(destination, count, source) { +var ThrottleTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrottleTimeSubscriber, _super); + function ThrottleTimeSubscriber(destination, duration, scheduler, leading, trailing) { var _this = _super.call(this, destination) || this; - _this.count = count; - _this.source = source; + _this.duration = duration; + _this.scheduler = scheduler; + _this.leading = leading; + _this.trailing = trailing; + _this._hasTrailingValue = false; + _this._trailingValue = null; return _this; } - RetrySubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var _a = this, source = _a.source, count = _a.count; - if (count === 0) { - return _super.prototype.error.call(this, err); + ThrottleTimeSubscriber.prototype._next = function (value) { + if (this.throttled) { + if (this.trailing) { + this._trailingValue = value; + this._hasTrailingValue = true; } - else if (count > -1) { - this.count = count - 1; + } + else { + this.add(this.throttled = this.scheduler.schedule(dispatchNext, this.duration, { subscriber: this })); + if (this.leading) { + this.destination.next(value); + } + else if (this.trailing) { + this._trailingValue = value; + this._hasTrailingValue = true; } - source.subscribe(this._unsubscribeAndRecycle()); } }; - return RetrySubscriber; + ThrottleTimeSubscriber.prototype._complete = function () { + if (this._hasTrailingValue) { + this.destination.next(this._trailingValue); + this.destination.complete(); + } + else { + this.destination.complete(); + } + }; + ThrottleTimeSubscriber.prototype.clearThrottle = function () { + var throttled = this.throttled; + if (throttled) { + if (this.trailing && this._hasTrailingValue) { + this.destination.next(this._trailingValue); + this._trailingValue = null; + this._hasTrailingValue = false; + } + throttled.unsubscribe(); + this.remove(throttled); + this.throttled = null; + } + }; + return ThrottleTimeSubscriber; }(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=retry.js.map +function dispatchNext(arg) { + var subscriber = arg.subscriber; + subscriber.clearThrottle(); +} +//# sourceMappingURL=throttleTime.js.map + + +/***/ }), +/* 487 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__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__(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 */ + + + + +function timeInterval(scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; + } + return function (source) { + return Object(_observable_defer__WEBPACK_IMPORTED_MODULE_2__["defer"])(function () { + return source.pipe(Object(_scan__WEBPACK_IMPORTED_MODULE_1__["scan"])(function (_a, value) { + var current = _a.current; + return ({ value: value, current: scheduler.now(), last: current }); + }, { current: scheduler.now(), value: undefined, last: undefined }), Object(_map__WEBPACK_IMPORTED_MODULE_3__["map"])(function (_a) { + var current = _a.current, last = _a.last, value = _a.value; + return new TimeInterval(value, current - last); + })); + }); + }; +} +var TimeInterval = /*@__PURE__*/ (function () { + function TimeInterval(value, interval) { + this.value = value; + this.interval = interval; + } + return TimeInterval; +}()); + +//# sourceMappingURL=timeInterval.js.map + + +/***/ }), +/* 488 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__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__(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 */ + + + + +function timeout(due, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; + } + return Object(_timeoutWith__WEBPACK_IMPORTED_MODULE_2__["timeoutWith"])(due, Object(_observable_throwError__WEBPACK_IMPORTED_MODULE_3__["throwError"])(new _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__["TimeoutError"]()), scheduler); +} +//# sourceMappingURL=timeout.js.map /***/ }), -/* 454 */ +/* 489 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return retryWhen; }); +/* 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 _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 _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); +/* 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 */ -function retryWhen(notifier) { - return function (source) { return source.lift(new RetryWhenOperator(notifier, source)); }; +function timeoutWith(due, withObservable, scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; + } + return function (source) { + var absoluteTimeout = Object(_util_isDate__WEBPACK_IMPORTED_MODULE_2__["isDate"])(due); + var waitFor = absoluteTimeout ? (+due - scheduler.now()) : Math.abs(due); + return source.lift(new TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler)); + }; } -var RetryWhenOperator = /*@__PURE__*/ (function () { - function RetryWhenOperator(notifier, source) { - this.notifier = notifier; - this.source = source; +var TimeoutWithOperator = /*@__PURE__*/ (function () { + function TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler) { + this.waitFor = waitFor; + this.absoluteTimeout = absoluteTimeout; + this.withObservable = withObservable; + this.scheduler = scheduler; } - RetryWhenOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new RetryWhenSubscriber(subscriber, this.notifier, this.source)); + TimeoutWithOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new TimeoutWithSubscriber(subscriber, this.absoluteTimeout, this.waitFor, this.withObservable, this.scheduler)); }; - return RetryWhenOperator; + return TimeoutWithOperator; }()); -var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](RetryWhenSubscriber, _super); - function RetryWhenSubscriber(destination, notifier, source) { +var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TimeoutWithSubscriber, _super); + function TimeoutWithSubscriber(destination, absoluteTimeout, waitFor, withObservable, scheduler) { var _this = _super.call(this, destination) || this; - _this.notifier = notifier; - _this.source = source; + _this.absoluteTimeout = absoluteTimeout; + _this.waitFor = waitFor; + _this.withObservable = withObservable; + _this.scheduler = scheduler; + _this.scheduleTimeout(); return _this; } - RetryWhenSubscriber.prototype.error = function (err) { - if (!this.isStopped) { - var errors = this.errors; - var retries = this.retries; - var retriesSubscription = this.retriesSubscription; - if (!retries) { - errors = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - try { - var notifier = this.notifier; - retries = notifier(errors); - } - catch (e) { - return _super.prototype.error.call(this, e); - } - retriesSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, retries); - } - else { - this.errors = null; - this.retriesSubscription = null; - } - this._unsubscribeAndRecycle(); - this.errors = errors; - this.retries = retries; - this.retriesSubscription = retriesSubscription; - errors.next(err); - } + TimeoutWithSubscriber.dispatchTimeout = function (subscriber) { + var withObservable = subscriber.withObservable; + subscriber._unsubscribeAndRecycle(); + subscriber.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["innerSubscribe"])(withObservable, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleInnerSubscriber"](subscriber))); }; - RetryWhenSubscriber.prototype._unsubscribe = function () { - var _a = this, errors = _a.errors, retriesSubscription = _a.retriesSubscription; - if (errors) { - errors.unsubscribe(); - this.errors = null; + TimeoutWithSubscriber.prototype.scheduleTimeout = function () { + var action = this.action; + if (action) { + this.action = action.schedule(this, this.waitFor); } - if (retriesSubscription) { - retriesSubscription.unsubscribe(); - this.retriesSubscription = null; + else { + this.add(this.action = this.scheduler.schedule(TimeoutWithSubscriber.dispatchTimeout, this.waitFor, this)); } - this.retries = null; }; - RetryWhenSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - var _unsubscribe = this._unsubscribe; - this._unsubscribe = null; - this._unsubscribeAndRecycle(); - this._unsubscribe = _unsubscribe; - this.source.subscribe(this); + TimeoutWithSubscriber.prototype._next = function (value) { + if (!this.absoluteTimeout) { + this.scheduleTimeout(); + } + _super.prototype._next.call(this, value); }; - return RetryWhenSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=retryWhen.js.map + TimeoutWithSubscriber.prototype._unsubscribe = function () { + this.action = undefined; + this.scheduler = null; + this.withObservable = null; + }; + return TimeoutWithSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_3__["SimpleOuterSubscriber"])); +//# sourceMappingURL=timeoutWith.js.map /***/ }), -/* 455 */ +/* 490 */ /***/ (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 export (binding) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return timestamp; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Timestamp", function() { return Timestamp; }); +/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); +/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(66); +/** PURE_IMPORTS_START _scheduler_async,_map PURE_IMPORTS_END */ -function sample(notifier) { - return function (source) { return source.lift(new SampleOperator(notifier)); }; +function timestamp(scheduler) { + if (scheduler === void 0) { + scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; + } + return Object(_map__WEBPACK_IMPORTED_MODULE_1__["map"])(function (value) { return new Timestamp(value, scheduler.now()); }); } -var SampleOperator = /*@__PURE__*/ (function () { - function SampleOperator(notifier) { - this.notifier = notifier; +var Timestamp = /*@__PURE__*/ (function () { + function Timestamp(value, timestamp) { + this.value = value; + this.timestamp = timestamp; } - 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)); - return subscription; - }; - return SampleOperator; + return Timestamp; }()); -var SampleSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SampleSubscriber, _super); - function SampleSubscriber() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.hasValue = false; - return _this; - } - SampleSubscriber.prototype._next = function (value) { - this.value = value; - this.hasValue = true; - }; - SampleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.emitValue(); - }; - SampleSubscriber.prototype.notifyComplete = function () { - this.emitValue(); - }; - SampleSubscriber.prototype.emitValue = function () { - if (this.hasValue) { - this.hasValue = false; - this.destination.next(this.value); - } - }; - return SampleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=sample.js.map + +//# sourceMappingURL=timestamp.js.map /***/ }), -/* 456 */ +/* 491 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return sampleTime; }); -/* 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); -/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async PURE_IMPORTS_END */ - - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return toArray; }); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(446); +/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ -function sampleTime(period, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; +function toArrayReducer(arr, item, index) { + if (index === 0) { + return [item]; } - return function (source) { return source.lift(new SampleTimeOperator(period, scheduler)); }; + arr.push(item); + return arr; } -var SampleTimeOperator = /*@__PURE__*/ (function () { - function SampleTimeOperator(period, scheduler) { - this.period = period; - this.scheduler = scheduler; - } - SampleTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SampleTimeSubscriber(subscriber, this.period, this.scheduler)); - }; - return SampleTimeOperator; -}()); -var SampleTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SampleTimeSubscriber, _super); - function SampleTimeSubscriber(destination, period, scheduler) { - var _this = _super.call(this, destination) || this; - _this.period = period; - _this.scheduler = scheduler; - _this.hasValue = false; - _this.add(scheduler.schedule(dispatchNotification, period, { subscriber: _this, period: period })); - return _this; - } - SampleTimeSubscriber.prototype._next = function (value) { - this.lastValue = value; - this.hasValue = true; - }; - SampleTimeSubscriber.prototype.notifyNext = function () { - if (this.hasValue) { - this.hasValue = false; - this.destination.next(this.lastValue); - } - }; - return SampleTimeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -function dispatchNotification(state) { - var subscriber = state.subscriber, period = state.period; - subscriber.notifyNext(); - this.schedule(state, period); +function toArray() { + return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(toArrayReducer, []); } -//# sourceMappingURL=sampleTime.js.map +//# sourceMappingURL=toArray.js.map /***/ }), -/* 457 */ +/* 492 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return sequenceEqual; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SequenceEqualOperator", function() { return SequenceEqualOperator; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SequenceEqualSubscriber", function() { return SequenceEqualSubscriber; }); +/* 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 _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); +/* harmony import */ var _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); +/** PURE_IMPORTS_START tslib,_Subject,_innerSubscribe PURE_IMPORTS_END */ -function sequenceEqual(compareTo, comparator) { - return function (source) { return source.lift(new SequenceEqualOperator(compareTo, comparator)); }; + +function window(windowBoundaries) { + return function windowOperatorFunction(source) { + return source.lift(new WindowOperator(windowBoundaries)); + }; } -var SequenceEqualOperator = /*@__PURE__*/ (function () { - function SequenceEqualOperator(compareTo, comparator) { - this.compareTo = compareTo; - this.comparator = comparator; +var WindowOperator = /*@__PURE__*/ (function () { + function WindowOperator(windowBoundaries) { + this.windowBoundaries = windowBoundaries; } - SequenceEqualOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SequenceEqualSubscriber(subscriber, this.compareTo, this.comparator)); + WindowOperator.prototype.call = function (subscriber, source) { + var windowSubscriber = new WindowSubscriber(subscriber); + var sourceSubscription = source.subscribe(windowSubscriber); + if (!sourceSubscription.closed) { + windowSubscriber.add(Object(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["innerSubscribe"])(this.windowBoundaries, new _innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleInnerSubscriber"](windowSubscriber))); + } + return sourceSubscription; }; - return SequenceEqualOperator; + return WindowOperator; }()); - -var SequenceEqualSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SequenceEqualSubscriber, _super); - function SequenceEqualSubscriber(destination, compareTo, comparator) { +var WindowSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowSubscriber, _super); + function WindowSubscriber(destination) { var _this = _super.call(this, destination) || this; - _this.compareTo = compareTo; - _this.comparator = comparator; - _this._a = []; - _this._b = []; - _this._oneComplete = false; - _this.destination.add(compareTo.subscribe(new SequenceEqualCompareToSubscriber(destination, _this))); + _this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + destination.next(_this.window); return _this; } - SequenceEqualSubscriber.prototype._next = function (value) { - if (this._oneComplete && this._b.length === 0) { - this.emit(false); - } - else { - this._a.push(value); - this.checkValues(); - } - }; - SequenceEqualSubscriber.prototype._complete = function () { - if (this._oneComplete) { - this.emit(this._a.length === 0 && this._b.length === 0); - } - else { - this._oneComplete = true; - } - this.unsubscribe(); + WindowSubscriber.prototype.notifyNext = function () { + this.openWindow(); }; - SequenceEqualSubscriber.prototype.checkValues = function () { - var _c = this, _a = _c._a, _b = _c._b, comparator = _c.comparator; - while (_a.length > 0 && _b.length > 0) { - var a = _a.shift(); - var b = _b.shift(); - var areEqual = false; - try { - areEqual = comparator ? comparator(a, b) : a === b; - } - catch (e) { - this.destination.error(e); - } - if (!areEqual) { - this.emit(false); - } - } + WindowSubscriber.prototype.notifyError = function (error) { + this._error(error); }; - SequenceEqualSubscriber.prototype.emit = function (value) { - var destination = this.destination; - destination.next(value); - destination.complete(); + WindowSubscriber.prototype.notifyComplete = function () { + this._complete(); }; - SequenceEqualSubscriber.prototype.nextB = function (value) { - if (this._oneComplete && this._a.length === 0) { - this.emit(false); - } - else { - this._b.push(value); - this.checkValues(); - } + WindowSubscriber.prototype._next = function (value) { + this.window.next(value); }; - SequenceEqualSubscriber.prototype.completeB = function () { - if (this._oneComplete) { - this.emit(this._a.length === 0 && this._b.length === 0); - } - else { - this._oneComplete = true; - } + WindowSubscriber.prototype._error = function (err) { + this.window.error(err); + this.destination.error(err); }; - return SequenceEqualSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); - -var SequenceEqualCompareToSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SequenceEqualCompareToSubscriber, _super); - function SequenceEqualCompareToSubscriber(destination, parent) { - var _this = _super.call(this, destination) || this; - _this.parent = parent; - return _this; - } - SequenceEqualCompareToSubscriber.prototype._next = function (value) { - this.parent.nextB(value); + WindowSubscriber.prototype._complete = function () { + this.window.complete(); + this.destination.complete(); }; - SequenceEqualCompareToSubscriber.prototype._error = function (err) { - this.parent.error(err); - this.unsubscribe(); + WindowSubscriber.prototype._unsubscribe = function () { + this.window = null; }; - SequenceEqualCompareToSubscriber.prototype._complete = function () { - this.parent.completeB(); - this.unsubscribe(); + WindowSubscriber.prototype.openWindow = function () { + var prevWindow = this.window; + if (prevWindow) { + prevWindow.complete(); + } + var destination = this.destination; + var newWindow = this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + destination.next(newWindow); }; - return SequenceEqualCompareToSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=sequenceEqual.js.map + return WindowSubscriber; +}(_innerSubscribe__WEBPACK_IMPORTED_MODULE_2__["SimpleOuterSubscriber"])); +//# sourceMappingURL=window.js.map /***/ }), -/* 458 */ +/* 493 */ /***/ (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__(441); -/* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return windowCount; }); +/* 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 _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27); -/** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ +/** PURE_IMPORTS_START tslib,_Subscriber,_Subject PURE_IMPORTS_END */ -function shareSubjectFactory() { - return new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"](); -} -function share() { - return function (source) { return Object(_refCount__WEBPACK_IMPORTED_MODULE_1__["refCount"])()(Object(_multicast__WEBPACK_IMPORTED_MODULE_0__["multicast"])(shareSubjectFactory)(source)); }; +function windowCount(windowSize, startWindowEvery) { + if (startWindowEvery === void 0) { + startWindowEvery = 0; + } + return function windowCountOperatorFunction(source) { + return source.lift(new WindowCountOperator(windowSize, startWindowEvery)); + }; } -//# sourceMappingURL=share.js.map - - -/***/ }), -/* 459 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return shareReplay; }); -/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33); -/** PURE_IMPORTS_START _ReplaySubject PURE_IMPORTS_END */ - -function shareReplay(configOrBufferSize, windowTime, scheduler) { - var config; - if (configOrBufferSize && typeof configOrBufferSize === 'object') { - config = configOrBufferSize; +var WindowCountOperator = /*@__PURE__*/ (function () { + function WindowCountOperator(windowSize, startWindowEvery) { + this.windowSize = windowSize; + this.startWindowEvery = startWindowEvery; } - else { - config = { - bufferSize: configOrBufferSize, - windowTime: windowTime, - refCount: false, - scheduler: scheduler - }; + WindowCountOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WindowCountSubscriber(subscriber, this.windowSize, this.startWindowEvery)); + }; + return WindowCountOperator; +}()); +var WindowCountSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowCountSubscriber, _super); + function WindowCountSubscriber(destination, windowSize, startWindowEvery) { + var _this = _super.call(this, destination) || this; + _this.destination = destination; + _this.windowSize = windowSize; + _this.startWindowEvery = startWindowEvery; + _this.windows = [new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"]()]; + _this.count = 0; + destination.next(_this.windows[0]); + return _this; } - return function (source) { return source.lift(shareReplayOperator(config)); }; -} -function shareReplayOperator(_a) { - var _b = _a.bufferSize, bufferSize = _b === void 0 ? Number.POSITIVE_INFINITY : _b, _c = _a.windowTime, windowTime = _c === void 0 ? Number.POSITIVE_INFINITY : _c, useRefCount = _a.refCount, scheduler = _a.scheduler; - var subject; - var refCount = 0; - var subscription; - var hasError = false; - var isComplete = false; - return function shareReplayOperation(source) { - refCount++; - if (!subject || hasError) { - hasError = false; - subject = new _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__["ReplaySubject"](bufferSize, windowTime, scheduler); - subscription = source.subscribe({ - next: function (value) { subject.next(value); }, - error: function (err) { - hasError = true; - subject.error(err); - }, - complete: function () { - isComplete = true; - subscription = undefined; - subject.complete(); - }, - }); + WindowCountSubscriber.prototype._next = function (value) { + var startWindowEvery = (this.startWindowEvery > 0) ? this.startWindowEvery : this.windowSize; + var destination = this.destination; + var windowSize = this.windowSize; + var windows = this.windows; + var len = windows.length; + for (var i = 0; i < len && !this.closed; i++) { + windows[i].next(value); } - var innerSub = subject.subscribe(this); - this.add(function () { - refCount--; - innerSub.unsubscribe(); - if (subscription && !isComplete && useRefCount && refCount === 0) { - subscription.unsubscribe(); - subscription = undefined; - subject = undefined; + var c = this.count - windowSize + 1; + if (c >= 0 && c % startWindowEvery === 0 && !this.closed) { + windows.shift().complete(); + } + if (++this.count % startWindowEvery === 0 && !this.closed) { + var window_1 = new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"](); + windows.push(window_1); + destination.next(window_1); + } + }; + WindowCountSubscriber.prototype._error = function (err) { + var windows = this.windows; + if (windows) { + while (windows.length > 0 && !this.closed) { + windows.shift().error(err); } - }); + } + this.destination.error(err); + }; + WindowCountSubscriber.prototype._complete = function () { + var windows = this.windows; + if (windows) { + while (windows.length > 0 && !this.closed) { + windows.shift().complete(); + } + } + this.destination.complete(); }; -} -//# sourceMappingURL=shareReplay.js.map + WindowCountSubscriber.prototype._unsubscribe = function () { + this.count = 0; + this.windows = null; + }; + return WindowCountSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); +//# sourceMappingURL=windowCount.js.map /***/ }), -/* 460 */ +/* 494 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "single", function() { return single; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return windowTime; }); /* 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 _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(63); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_EmptyError PURE_IMPORTS_END */ +/* 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__(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 */ -function single(predicate) { - return function (source) { return source.lift(new SingleOperator(predicate, source)); }; + + + +function windowTime(windowTimeSpan) { + var scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; + var windowCreationInterval = null; + var maxWindowSize = Number.POSITIVE_INFINITY; + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[3])) { + scheduler = arguments[3]; + } + if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[2])) { + scheduler = arguments[2]; + } + else if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_4__["isNumeric"])(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 = Number(arguments[1]); + } + return function windowTimeOperatorFunction(source) { + return source.lift(new WindowTimeOperator(windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler)); + }; } -var SingleOperator = /*@__PURE__*/ (function () { - function SingleOperator(predicate, source) { - this.predicate = predicate; - this.source = source; +var WindowTimeOperator = /*@__PURE__*/ (function () { + function WindowTimeOperator(windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler) { + this.windowTimeSpan = windowTimeSpan; + this.windowCreationInterval = windowCreationInterval; + this.maxWindowSize = maxWindowSize; + this.scheduler = scheduler; } - SingleOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SingleSubscriber(subscriber, this.predicate, this.source)); + WindowTimeOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WindowTimeSubscriber(subscriber, this.windowTimeSpan, this.windowCreationInterval, this.maxWindowSize, this.scheduler)); }; - return SingleOperator; + return WindowTimeOperator; }()); -var SingleSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SingleSubscriber, _super); - function SingleSubscriber(destination, predicate, source) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.source = source; - _this.seenValue = false; - _this.index = 0; +var CountedSubject = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CountedSubject, _super); + function CountedSubject() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this._numberOfNextedValues = 0; return _this; } - SingleSubscriber.prototype.applySingleValue = function (value) { - if (this.seenValue) { - this.destination.error('Sequence contains more than one element'); + CountedSubject.prototype.next = function (value) { + this._numberOfNextedValues++; + _super.prototype.next.call(this, value); + }; + Object.defineProperty(CountedSubject.prototype, "numberOfNextedValues", { + get: function () { + return this._numberOfNextedValues; + }, + enumerable: true, + configurable: true + }); + return CountedSubject; +}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); +var WindowTimeSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowTimeSubscriber, _super); + function WindowTimeSubscriber(destination, windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler) { + var _this = _super.call(this, destination) || this; + _this.destination = destination; + _this.windowTimeSpan = windowTimeSpan; + _this.windowCreationInterval = windowCreationInterval; + _this.maxWindowSize = maxWindowSize; + _this.scheduler = scheduler; + _this.windows = []; + var window = _this.openWindow(); + if (windowCreationInterval !== null && windowCreationInterval >= 0) { + var closeState = { subscriber: _this, window: window, context: null }; + var creationState = { windowTimeSpan: windowTimeSpan, windowCreationInterval: windowCreationInterval, subscriber: _this, scheduler: scheduler }; + _this.add(scheduler.schedule(dispatchWindowClose, windowTimeSpan, closeState)); + _this.add(scheduler.schedule(dispatchWindowCreation, windowCreationInterval, creationState)); } else { - this.seenValue = true; - this.singleValue = value; + var timeSpanOnlyState = { subscriber: _this, window: window, windowTimeSpan: windowTimeSpan }; + _this.add(scheduler.schedule(dispatchWindowTimeSpanOnly, windowTimeSpan, timeSpanOnlyState)); } - }; - SingleSubscriber.prototype._next = function (value) { - var index = this.index++; - if (this.predicate) { - this.tryNext(value, index); + return _this; + } + WindowTimeSubscriber.prototype._next = function (value) { + var windows = this.windows; + var len = windows.length; + for (var i = 0; i < len; i++) { + var window_1 = windows[i]; + if (!window_1.closed) { + window_1.next(value); + if (window_1.numberOfNextedValues >= this.maxWindowSize) { + this.closeWindow(window_1); + } + } } - else { - this.applySingleValue(value); + }; + WindowTimeSubscriber.prototype._error = function (err) { + var windows = this.windows; + while (windows.length > 0) { + windows.shift().error(err); } + this.destination.error(err); }; - SingleSubscriber.prototype.tryNext = function (value, index) { - try { - if (this.predicate(value, index, this.source)) { - this.applySingleValue(value); + WindowTimeSubscriber.prototype._complete = function () { + var windows = this.windows; + while (windows.length > 0) { + var window_2 = windows.shift(); + if (!window_2.closed) { + window_2.complete(); } } - catch (err) { - this.destination.error(err); - } + this.destination.complete(); }; - SingleSubscriber.prototype._complete = function () { + WindowTimeSubscriber.prototype.openWindow = function () { + var window = new CountedSubject(); + this.windows.push(window); var destination = this.destination; - if (this.index > 0) { - destination.next(this.seenValue ? this.singleValue : undefined); - destination.complete(); - } - else { - destination.error(new _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__["EmptyError"]); - } + destination.next(window); + return window; }; - return SingleSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=single.js.map + WindowTimeSubscriber.prototype.closeWindow = function (window) { + window.complete(); + var windows = this.windows; + windows.splice(windows.indexOf(window), 1); + }; + return WindowTimeSubscriber; +}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); +function dispatchWindowTimeSpanOnly(state) { + var subscriber = state.subscriber, windowTimeSpan = state.windowTimeSpan, window = state.window; + if (window) { + subscriber.closeWindow(window); + } + state.window = subscriber.openWindow(); + this.schedule(state, windowTimeSpan); +} +function dispatchWindowCreation(state) { + var windowTimeSpan = state.windowTimeSpan, subscriber = state.subscriber, scheduler = state.scheduler, windowCreationInterval = state.windowCreationInterval; + var window = subscriber.openWindow(); + var action = this; + var context = { action: action, subscription: null }; + var timeSpanState = { subscriber: subscriber, window: window, context: context }; + context.subscription = scheduler.schedule(dispatchWindowClose, windowTimeSpan, timeSpanState); + action.add(context.subscription); + action.schedule(state, windowCreationInterval); +} +function dispatchWindowClose(state) { + var subscriber = state.subscriber, window = state.window, context = state.context; + if (context && context.action && context.subscription) { + context.action.remove(context.subscription); + } + subscriber.closeWindow(window); +} +//# sourceMappingURL=windowTime.js.map /***/ }), -/* 461 */ +/* 495 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return skip; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return windowToggle; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27); +/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17); +/* 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,_Subject,_Subscription,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function skip(count) { - return function (source) { return source.lift(new SkipOperator(count)); }; + + + +function windowToggle(openings, closingSelector) { + return function (source) { return source.lift(new WindowToggleOperator(openings, closingSelector)); }; } -var SkipOperator = /*@__PURE__*/ (function () { - function SkipOperator(total) { - this.total = total; +var WindowToggleOperator = /*@__PURE__*/ (function () { + function WindowToggleOperator(openings, closingSelector) { + this.openings = openings; + this.closingSelector = closingSelector; } - SkipOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SkipSubscriber(subscriber, this.total)); + WindowToggleOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WindowToggleSubscriber(subscriber, this.openings, this.closingSelector)); }; - return SkipOperator; + return WindowToggleOperator; }()); -var SkipSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipSubscriber, _super); - function SkipSubscriber(destination, total) { +var WindowToggleSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowToggleSubscriber, _super); + function WindowToggleSubscriber(destination, openings, closingSelector) { var _this = _super.call(this, destination) || this; - _this.total = total; - _this.count = 0; + _this.openings = openings; + _this.closingSelector = closingSelector; + _this.contexts = []; + _this.add(_this.openSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(_this, openings, openings)); return _this; } - SkipSubscriber.prototype._next = function (x) { - if (++this.count > this.total) { - this.destination.next(x); + WindowToggleSubscriber.prototype._next = function (value) { + var contexts = this.contexts; + if (contexts) { + var len = contexts.length; + for (var i = 0; i < len; i++) { + contexts[i].window.next(value); + } } }; - return SkipSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=skip.js.map - - -/***/ }), -/* 462 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return skipLast; }); -/* 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 _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(62); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_ArgumentOutOfRangeError PURE_IMPORTS_END */ - - - -function skipLast(count) { - return function (source) { return source.lift(new SkipLastOperator(count)); }; -} -var SkipLastOperator = /*@__PURE__*/ (function () { - function SkipLastOperator(_skipCount) { - this._skipCount = _skipCount; - if (this._skipCount < 0) { - throw new _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_2__["ArgumentOutOfRangeError"]; + WindowToggleSubscriber.prototype._error = function (err) { + var contexts = this.contexts; + this.contexts = null; + if (contexts) { + var len = contexts.length; + var index = -1; + while (++index < len) { + var context_1 = contexts[index]; + context_1.window.error(err); + context_1.subscription.unsubscribe(); + } } - } - SkipLastOperator.prototype.call = function (subscriber, source) { - if (this._skipCount === 0) { - return source.subscribe(new _Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"](subscriber)); + _super.prototype._error.call(this, err); + }; + WindowToggleSubscriber.prototype._complete = function () { + var contexts = this.contexts; + this.contexts = null; + if (contexts) { + var len = contexts.length; + var index = -1; + while (++index < len) { + var context_2 = contexts[index]; + context_2.window.complete(); + context_2.subscription.unsubscribe(); + } } - else { - return source.subscribe(new SkipLastSubscriber(subscriber, this._skipCount)); + _super.prototype._complete.call(this); + }; + WindowToggleSubscriber.prototype._unsubscribe = function () { + var contexts = this.contexts; + this.contexts = null; + if (contexts) { + var len = contexts.length; + var index = -1; + while (++index < len) { + var context_3 = contexts[index]; + context_3.window.unsubscribe(); + context_3.subscription.unsubscribe(); + } } }; - return SkipLastOperator; -}()); -var SkipLastSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipLastSubscriber, _super); - function SkipLastSubscriber(destination, _skipCount) { - var _this = _super.call(this, destination) || this; - _this._skipCount = _skipCount; - _this._count = 0; - _this._ring = new Array(_skipCount); - return _this; - } - SkipLastSubscriber.prototype._next = function (value) { - var skipCount = this._skipCount; - var count = this._count++; - if (count < skipCount) { - this._ring[count] = value; + WindowToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { + if (outerValue === this.openings) { + var closingNotifier = void 0; + try { + var closingSelector = this.closingSelector; + closingNotifier = closingSelector(innerValue); + } + catch (e) { + return this.error(e); + } + var window_1 = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](); + var context_4 = { window: window_1, subscription: subscription }; + this.contexts.push(context_4); + var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, closingNotifier, context_4); + if (innerSubscription.closed) { + this.closeWindow(this.contexts.length - 1); + } + else { + innerSubscription.context = context_4; + subscription.add(innerSubscription); + } + this.destination.next(window_1); } else { - var currentIndex = count % skipCount; - var ring = this._ring; - var oldValue = ring[currentIndex]; - ring[currentIndex] = value; - this.destination.next(oldValue); + this.closeWindow(this.contexts.indexOf(outerValue)); } }; - return SkipLastSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=skipLast.js.map + WindowToggleSubscriber.prototype.notifyError = function (err) { + this.error(err); + }; + WindowToggleSubscriber.prototype.notifyComplete = function (inner) { + if (inner !== this.openSubscription) { + this.closeWindow(this.contexts.indexOf(inner.context)); + } + }; + WindowToggleSubscriber.prototype.closeWindow = function (index) { + if (index === -1) { + return; + } + var contexts = this.contexts; + var context = contexts[index]; + var window = context.window, subscription = context.subscription; + contexts.splice(index, 1); + window.complete(); + subscription.unsubscribe(); + }; + return WindowToggleSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); +//# sourceMappingURL=windowToggle.js.map /***/ }), -/* 463 */ +/* 496 */ /***/ (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 export (binding) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return windowWhen; }); /* 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 _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,_OuterSubscriber,_InnerSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +/** PURE_IMPORTS_START tslib,_Subject,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ -function skipUntil(notifier) { - return function (source) { return source.lift(new SkipUntilOperator(notifier)); }; +function windowWhen(closingSelector) { + return function windowWhenOperatorFunction(source) { + return source.lift(new WindowOperator(closingSelector)); + }; } -var SkipUntilOperator = /*@__PURE__*/ (function () { - function SkipUntilOperator(notifier) { - this.notifier = notifier; +var WindowOperator = /*@__PURE__*/ (function () { + function WindowOperator(closingSelector) { + this.closingSelector = closingSelector; } - SkipUntilOperator.prototype.call = function (destination, source) { - return source.subscribe(new SkipUntilSubscriber(destination, this.notifier)); + WindowOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WindowSubscriber(subscriber, this.closingSelector)); }; - return SkipUntilOperator; + return WindowOperator; }()); -var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipUntilSubscriber, _super); - function SkipUntilSubscriber(destination, notifier) { +var WindowSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowSubscriber, _super); + function WindowSubscriber(destination, closingSelector) { var _this = _super.call(this, destination) || this; - _this.hasValue = false; - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](_this, undefined, undefined); - _this.add(innerSubscriber); - _this.innerSubscription = innerSubscriber; - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(_this, notifier, undefined, undefined, innerSubscriber); - if (innerSubscription !== innerSubscriber) { - _this.add(innerSubscription); - _this.innerSubscription = innerSubscription; - } + _this.destination = destination; + _this.closingSelector = closingSelector; + _this.openWindow(); return _this; } - SkipUntilSubscriber.prototype._next = function (value) { - if (this.hasValue) { - _super.prototype._next.call(this, value); - } + WindowSubscriber.prototype.notifyNext = function (_outerValue, _innerValue, _outerIndex, _innerIndex, innerSub) { + this.openWindow(innerSub); }; - SkipUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.hasValue = true; - if (this.innerSubscription) { - this.innerSubscription.unsubscribe(); + WindowSubscriber.prototype.notifyError = function (error) { + this._error(error); + }; + WindowSubscriber.prototype.notifyComplete = function (innerSub) { + this.openWindow(innerSub); + }; + WindowSubscriber.prototype._next = function (value) { + this.window.next(value); + }; + WindowSubscriber.prototype._error = function (err) { + this.window.error(err); + this.destination.error(err); + this.unsubscribeClosingNotification(); + }; + WindowSubscriber.prototype._complete = function () { + this.window.complete(); + this.destination.complete(); + this.unsubscribeClosingNotification(); + }; + WindowSubscriber.prototype.unsubscribeClosingNotification = function () { + if (this.closingNotification) { + this.closingNotification.unsubscribe(); } }; - SkipUntilSubscriber.prototype.notifyComplete = function () { + WindowSubscriber.prototype.openWindow = function (innerSub) { + if (innerSub === void 0) { + innerSub = null; + } + if (innerSub) { + this.remove(innerSub); + innerSub.unsubscribe(); + } + var prevWindow = this.window; + if (prevWindow) { + prevWindow.complete(); + } + var window = this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); + this.destination.next(window); + var closingNotifier; + try { + var closingSelector = this.closingSelector; + closingNotifier = closingSelector(); + } + catch (e) { + this.destination.error(e); + this.window.error(e); + return; + } + this.add(this.closingNotification = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, closingNotifier)); }; - return SkipUntilSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=skipUntil.js.map + return WindowSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); +//# sourceMappingURL=windowWhen.js.map /***/ }), -/* 464 */ +/* 497 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return skipWhile; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return withLatestFrom; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ +/* 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 */ -function skipWhile(predicate) { - return function (source) { return source.lift(new SkipWhileOperator(predicate)); }; + +function withLatestFrom() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return function (source) { + var project; + if (typeof args[args.length - 1] === 'function') { + project = args.pop(); + } + var observables = args; + return source.lift(new WithLatestFromOperator(observables, project)); + }; } -var SkipWhileOperator = /*@__PURE__*/ (function () { - function SkipWhileOperator(predicate) { - this.predicate = predicate; +var WithLatestFromOperator = /*@__PURE__*/ (function () { + function WithLatestFromOperator(observables, project) { + this.observables = observables; + this.project = project; } - SkipWhileOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SkipWhileSubscriber(subscriber, this.predicate)); + WithLatestFromOperator.prototype.call = function (subscriber, source) { + return source.subscribe(new WithLatestFromSubscriber(subscriber, this.observables, this.project)); }; - return SkipWhileOperator; + return WithLatestFromOperator; }()); -var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SkipWhileSubscriber, _super); - function SkipWhileSubscriber(destination, predicate) { +var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { + tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WithLatestFromSubscriber, _super); + function WithLatestFromSubscriber(destination, observables, project) { var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.skipping = true; - _this.index = 0; + _this.observables = observables; + _this.project = project; + _this.toRespond = []; + var len = observables.length; + _this.values = new Array(len); + for (var i = 0; i < len; i++) { + _this.toRespond.push(i); + } + for (var i = 0; i < len; i++) { + var observable = observables[i]; + _this.add(Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(_this, observable, undefined, i)); + } return _this; } - SkipWhileSubscriber.prototype._next = function (value) { - var destination = this.destination; - if (this.skipping) { - this.tryCallPredicate(value); + WithLatestFromSubscriber.prototype.notifyNext = function (_outerValue, innerValue, outerIndex) { + this.values[outerIndex] = innerValue; + var toRespond = this.toRespond; + if (toRespond.length > 0) { + var found = toRespond.indexOf(outerIndex); + if (found !== -1) { + toRespond.splice(found, 1); + } } - if (!this.skipping) { - destination.next(value); + }; + WithLatestFromSubscriber.prototype.notifyComplete = function () { + }; + WithLatestFromSubscriber.prototype._next = function (value) { + if (this.toRespond.length === 0) { + var args = [value].concat(this.values); + if (this.project) { + this._tryProject(args); + } + else { + this.destination.next(args); + } } }; - SkipWhileSubscriber.prototype.tryCallPredicate = function (value) { + WithLatestFromSubscriber.prototype._tryProject = function (args) { + var result; try { - var result = this.predicate(value, this.index++); - this.skipping = Boolean(result); + result = this.project.apply(this, args); } catch (err) { this.destination.error(err); + return; } + this.destination.next(result); }; - return SkipWhileSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=skipWhile.js.map + return WithLatestFromSubscriber; +}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); +//# sourceMappingURL=withLatestFrom.js.map /***/ }), -/* 465 */ +/* 498 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return startWith; }); -/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(79); -/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45); -/** PURE_IMPORTS_START _observable_concat,_util_isScheduler PURE_IMPORTS_END */ - +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return zip; }); +/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(110); +/** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ -function startWith() { - var array = []; +function zip() { + var observables = []; for (var _i = 0; _i < arguments.length; _i++) { - array[_i] = arguments[_i]; - } - var scheduler = array[array.length - 1]; - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__["isScheduler"])(scheduler)) { - array.pop(); - return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(array, source, scheduler); }; - } - else { - return function (source) { return Object(_observable_concat__WEBPACK_IMPORTED_MODULE_0__["concat"])(array, source); }; + observables[_i] = arguments[_i]; } + return function zipOperatorFunction(source) { + return source.lift.call(_observable_zip__WEBPACK_IMPORTED_MODULE_0__["zip"].apply(void 0, [source].concat(observables))); + }; } -//# sourceMappingURL=startWith.js.map +//# sourceMappingURL=zip.js.map /***/ }), -/* 466 */ +/* 499 */ /***/ (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__(467); -/** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return zipAll; }); +/* harmony import */ var _observable_zip__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(110); +/** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ -function subscribeOn(scheduler, delay) { - if (delay === void 0) { - delay = 0; - } - return function subscribeOnOperatorFunction(source) { - return source.lift(new SubscribeOnOperator(scheduler, delay)); - }; +function zipAll(project) { + return function (source) { return source.lift(new _observable_zip__WEBPACK_IMPORTED_MODULE_0__["ZipOperator"](project)); }; } -var SubscribeOnOperator = /*@__PURE__*/ (function () { - function SubscribeOnOperator(scheduler, delay) { - this.scheduler = scheduler; - this.delay = delay; - } - SubscribeOnOperator.prototype.call = function (subscriber, source) { - return new _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__["SubscribeOnObservable"](source, this.delay, this.scheduler).subscribe(subscriber); - }; - return SubscribeOnOperator; -}()); -//# sourceMappingURL=subscribeOn.js.map +//# sourceMappingURL=zipAll.js.map /***/ }), -/* 467 */ +/* 500 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SubscribeOnObservable", function() { return SubscribeOnObservable; }); -/* 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); -/** PURE_IMPORTS_START tslib,_Observable,_scheduler_asap,_util_isNumeric PURE_IMPORTS_END */ +/* 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_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; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SubscribeOnObservable, _super); - function SubscribeOnObservable(source, delayTime, scheduler) { - if (delayTime === void 0) { - delayTime = 0; - } - if (scheduler === void 0) { - scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; - } - var _this = _super.call(this) || this; - _this.source = source; - _this.delayTime = delayTime; - _this.scheduler = scheduler; - if (!Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_3__["isNumeric"])(delayTime) || delayTime < 0) { - _this.delayTime = 0; - } - if (!scheduler || typeof scheduler.schedule !== 'function') { - _this.scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; - } - return _this; + +async function runCommand(command, config) { + try { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(`Running [${command.name}] command from [${config.rootPath}]`); + const kbn = await _utils_kibana__WEBPACK_IMPORTED_MODULE_4__["Kibana"].loadFrom(config.rootPath); + const projects = kbn.getFilteredProjects({ + skipKibanaPlugins: Boolean(config.options['skip-kibana-plugins']), + ossOnly: Boolean(config.options.oss), + exclude: toArray(config.options.exclude), + include: toArray(config.options.include) + }); + + if (projects.size === 0) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(`There are no projects found. Double check project name(s) in '-i/--include' and '-e/--exclude' filters.`); + return process.exit(1); } - SubscribeOnObservable.create = function (source, delay, scheduler) { - if (delay === void 0) { - delay = 0; - } - if (scheduler === void 0) { - scheduler = _scheduler_asap__WEBPACK_IMPORTED_MODULE_2__["asap"]; - } - return new SubscribeOnObservable(source, delay, scheduler); - }; - SubscribeOnObservable.dispatch = function (arg) { - var source = arg.source, subscriber = arg.subscriber; - return this.add(source.subscribe(subscriber)); - }; - SubscribeOnObservable.prototype._subscribe = function (subscriber) { - var delay = this.delayTime; - var source = this.source; - var scheduler = this.scheduler; - return scheduler.schedule(SubscribeOnObservable.dispatch, delay, { - source: source, subscriber: subscriber - }); - }; - return SubscribeOnObservable; -}(_Observable__WEBPACK_IMPORTED_MODULE_1__["Observable"])); -//# sourceMappingURL=SubscribeOnObservable.js.map + const projectGraph = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_2__["buildProjectGraph"])(projects); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(`Found ${projects.size.toString()} projects`); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(Object(_utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__["renderProjectsTree"])(config.rootPath, projects)); + await command.run(projects, projectGraph, _objectSpread(_objectSpread({}, config), {}, { + kbn + })); + } catch (error) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(`[${command.name}] failed:`); + + if (error instanceof _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"]) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(error.message); + const metaOutput = Object.entries(error.meta).map(([key, value]) => `${key}: ${value}`).join('\n'); + + if (metaOutput) { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info('Additional debugging info:\n'); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].indent(2); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(metaOutput); + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].indent(-2); + } + } else { + _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(error); + } + + process.exit(1); + } +} + +function toArray(value) { + if (value == null) { + return []; + } + return Array.isArray(value) ? value : [value]; +} /***/ }), -/* 468 */ +/* 501 */ /***/ (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__(469); -/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25); -/** PURE_IMPORTS_START _switchMap,_util_identity PURE_IMPORTS_END */ +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "renderProjectsTree", function() { return renderProjectsTree; }); +/* 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__); +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ -function switchAll() { - return Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(_util_identity__WEBPACK_IMPORTED_MODULE_1__["identity"]); +const projectKey = Symbol('__project'); +function renderProjectsTree(rootPath, projects) { + const projectsTree = buildProjectsTree(rootPath, projects); + return treeToString(createTreeStructure(projectsTree)); } -//# sourceMappingURL=switchAll.js.map +function treeToString(tree) { + return [tree.name].concat(childrenToStrings(tree.children, '')).join('\n'); +} -/***/ }), -/* 469 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +function childrenToStrings(tree, treePrefix) { + if (tree === undefined) { + return []; + } -"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 */ + let strings = []; + tree.forEach((node, index) => { + const isLastNode = tree.length - 1 === index; + const nodePrefix = isLastNode ? '└── ' : '├── '; + const childPrefix = isLastNode ? ' ' : '│ '; + const childrenPrefix = treePrefix + childPrefix; + strings.push(`${treePrefix}${nodePrefix}${node.name}`); + strings = strings.concat(childrenToStrings(node.children, childrenPrefix)); + }); + return strings; +} +function createTreeStructure(tree) { + let name; + const children = []; + for (const [dir, project] of tree.entries()) { + // This is a leaf node (aka a project) + if (typeof project === 'string') { + name = chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(project); + continue; + } // If there's only one project and the key indicates it's a leaf node, we + // know that we're at a package folder that contains a package.json, so we + // "inline it" so we don't get unnecessary levels, i.e. we'll just see + // `foo` instead of `foo -> foo`. + if (project.size === 1 && project.has(projectKey)) { + const projectName = project.get(projectKey); + children.push({ + children: [], + name: dirOrProjectName(dir, projectName) + }); + continue; + } + const subtree = createTreeStructure(project); // If the name is specified, we know there's a package at the "root" of the + // subtree itself. -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); })); })); }; + if (subtree.name !== undefined) { + const projectName = subtree.name; + children.push({ + children: subtree.children, + name: dirOrProjectName(dir, projectName) + }); + continue; + } // Special-case whenever we have one child, so we don't get unnecessary + // folders in the output. E.g. instead of `foo -> bar -> baz` we get + // `foo/bar/baz` instead. + + + if (subtree.children && subtree.children.length === 1) { + const child = subtree.children[0]; + const newName = chalk__WEBPACK_IMPORTED_MODULE_0___default.a.dim(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(dir.toString(), child.name)); + children.push({ + children: child.children, + name: newName + }); + continue; } - return function (source) { return source.lift(new SwitchMapOperator(project)); }; + + children.push({ + children: subtree.children, + name: chalk__WEBPACK_IMPORTED_MODULE_0___default.a.dim(dir.toString()) + }); + } + + return { + name, + children + }; } -var SwitchMapOperator = /*@__PURE__*/ (function () { - function SwitchMapOperator(project) { - this.project = project; + +function dirOrProjectName(dir, projectName) { + return dir === projectName ? chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(dir) : chalk__WEBPACK_IMPORTED_MODULE_0___default.a`{dim ${dir.toString()} ({reset.green ${projectName}})}`; +} + +function buildProjectsTree(rootPath, projects) { + const tree = new Map(); + + for (const project of projects.values()) { + if (rootPath === project.path) { + tree.set(projectKey, project.name); + } else { + const relativeProjectPath = path__WEBPACK_IMPORTED_MODULE_1___default.a.relative(rootPath, project.path); + addProjectToTree(tree, relativeProjectPath.split(path__WEBPACK_IMPORTED_MODULE_1___default.a.sep), project); } - SwitchMapOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new SwitchMapSubscriber(subscriber, this.project)); - }; - return SwitchMapOperator; -}()); -var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](SwitchMapSubscriber, _super); - function SwitchMapSubscriber(destination, project) { - var _this = _super.call(this, destination) || this; - _this.project = project; - _this.index = 0; - return _this; + } + + return tree; +} + +function addProjectToTree(tree, pathParts, project) { + if (pathParts.length === 0) { + tree.set(projectKey, project.name); + } else { + const [currentDir, ...rest] = pathParts; + + if (!tree.has(currentDir)) { + tree.set(currentDir, new Map()); } - SwitchMapSubscriber.prototype._next = function (value) { - var result; - var index = this.index++; - try { - result = this.project(value, index); - } - catch (error) { - this.destination.error(error); - return; - } - this._innerSub(result, value, index); - }; - SwitchMapSubscriber.prototype._innerSub = function (result, value, index) { - var innerSubscription = this.innerSubscription; - if (innerSubscription) { - innerSubscription.unsubscribe(); - } - var innerSubscriber = new _InnerSubscriber__WEBPACK_IMPORTED_MODULE_2__["InnerSubscriber"](this, value, index); - var destination = this.destination; - destination.add(innerSubscriber); - this.innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, result, undefined, undefined, innerSubscriber); - if (this.innerSubscription !== innerSubscriber) { - destination.add(this.innerSubscription); - } - }; - SwitchMapSubscriber.prototype._complete = function () { - var innerSubscription = this.innerSubscription; - if (!innerSubscription || innerSubscription.closed) { - _super.prototype._complete.call(this); - } - this.unsubscribe(); - }; - SwitchMapSubscriber.prototype._unsubscribe = function () { - this.innerSubscription = null; - }; - SwitchMapSubscriber.prototype.notifyComplete = function (innerSub) { - var destination = this.destination; - destination.remove(innerSub); - this.innerSubscription = null; - if (this.isStopped) { - _super.prototype._complete.call(this); - } - }; - SwitchMapSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.destination.next(innerValue); - }; - return SwitchMapSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=switchMap.js.map + const subtree = tree.get(currentDir); + addProjectToTree(subtree, rest, project); + } +} + +/***/ }), +/* 502 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__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__(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__(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__(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; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + + + + +/** + * Helper class for dealing with a set of projects as children of + * the Kibana project. The kbn/pm is currently implemented to be + * more generic, where everything is an operation of generic projects, + * but that leads to exceptions where we need the kibana project and + * do things like `project.get('kibana')!`. + * + * Using this helper we can restructre the generic list of projects + * as a Kibana object which encapulates all the projects in the + * workspace and knows about the root Kibana project. + */ + +class Kibana { + static async loadFrom(rootPath) { + return new Kibana(await Object(_projects__WEBPACK_IMPORTED_MODULE_4__["getProjects"])(rootPath, Object(_config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"])({ + rootPath + }))); + } -/***/ }), -/* 470 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + constructor(allWorkspaceProjects) { + this.allWorkspaceProjects = allWorkspaceProjects; -"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__(469); -/** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ + _defineProperty(this, "kibanaProject", void 0); -function switchMapTo(innerObservable, resultSelector) { - return resultSelector ? Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(function () { return innerObservable; }, resultSelector) : Object(_switchMap__WEBPACK_IMPORTED_MODULE_0__["switchMap"])(function () { return innerObservable; }); -} -//# sourceMappingURL=switchMapTo.js.map + const kibanaProject = allWorkspaceProjects.get('kibana'); + if (!kibanaProject) { + throw new TypeError('Unable to create Kibana object without all projects, including the Kibana project.'); + } -/***/ }), -/* 471 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + this.kibanaProject = kibanaProject; + } + /** make an absolute path by resolving subPath relative to the kibana repo */ -"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 */ + getAbsolute(...subPath) { + return path__WEBPACK_IMPORTED_MODULE_0___default.a.resolve(this.kibanaProject.path, ...subPath); + } + /** convert an absolute path to a relative path, relative to the kibana repo */ -function takeUntil(notifier) { - return function (source) { return source.lift(new TakeUntilOperator(notifier)); }; -} -var TakeUntilOperator = /*@__PURE__*/ (function () { - function TakeUntilOperator(notifier) { - this.notifier = notifier; - } - TakeUntilOperator.prototype.call = function (subscriber, source) { - var takeUntilSubscriber = new TakeUntilSubscriber(subscriber); - var notifierSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_2__["subscribeToResult"])(takeUntilSubscriber, this.notifier); - if (notifierSubscription && !takeUntilSubscriber.seenValue) { - takeUntilSubscriber.add(notifierSubscription); - return source.subscribe(takeUntilSubscriber); - } - return takeUntilSubscriber; - }; - return TakeUntilOperator; -}()); -var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeUntilSubscriber, _super); - function TakeUntilSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.seenValue = false; - return _this; - } - TakeUntilSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.seenValue = true; - this.complete(); - }; - TakeUntilSubscriber.prototype.notifyComplete = function () { - }; - return TakeUntilSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=takeUntil.js.map + getRelative(absolute) { + return path__WEBPACK_IMPORTED_MODULE_0___default.a.relative(this.kibanaProject.path, absolute); + } + /** get a copy of the map of all projects in the kibana workspace */ -/***/ }), -/* 472 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + getAllProjects() { + return new Map(this.allWorkspaceProjects); + } + /** determine if a project with the given name exists */ -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return takeWhile; }); -/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); -/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); -/** PURE_IMPORTS_START tslib,_Subscriber PURE_IMPORTS_END */ + + hasProject(name) { + return this.allWorkspaceProjects.has(name); + } + /** get a specific project, throws if the name is not known (use hasProject() first) */ -function takeWhile(predicate, inclusive) { - if (inclusive === void 0) { - inclusive = false; - } - return function (source) { - return source.lift(new TakeWhileOperator(predicate, inclusive)); - }; -} -var TakeWhileOperator = /*@__PURE__*/ (function () { - function TakeWhileOperator(predicate, inclusive) { - this.predicate = predicate; - this.inclusive = inclusive; - } - TakeWhileOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TakeWhileSubscriber(subscriber, this.predicate, this.inclusive)); - }; - return TakeWhileOperator; -}()); -var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TakeWhileSubscriber, _super); - function TakeWhileSubscriber(destination, predicate, inclusive) { - var _this = _super.call(this, destination) || this; - _this.predicate = predicate; - _this.inclusive = inclusive; - _this.index = 0; - return _this; + getProject(name) { + const project = this.allWorkspaceProjects.get(name); + + if (!project) { + throw new Error(`No package with name "${name}" in the workspace`); } - TakeWhileSubscriber.prototype._next = function (value) { - var destination = this.destination; - var result; - try { - result = this.predicate(value, this.index++); - } - catch (err) { - destination.error(err); - return; - } - this.nextOrComplete(value, result); - }; - TakeWhileSubscriber.prototype.nextOrComplete = function (value, predicateResult) { - var destination = this.destination; - if (Boolean(predicateResult)) { - destination.next(value); - } - else { - if (this.inclusive) { - destination.next(value); - } - destination.complete(); - } - }; - return TakeWhileSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=takeWhile.js.map + return project; + } + /** get a project and all of the projects it depends on in a ProjectMap */ -/***/ }), -/* 473 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return tap; }); -/* 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 _util_noop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(60); -/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(13); -/** PURE_IMPORTS_START tslib,_Subscriber,_util_noop,_util_isFunction PURE_IMPORTS_END */ + getProjectAndDeps(name) { + const project = this.getProject(name); + return Object(_projects__WEBPACK_IMPORTED_MODULE_4__["includeTransitiveProjects"])([project], this.allWorkspaceProjects); + } + /** filter the projects to just those matching certain paths/include/exclude tags */ + getFilteredProjects(options) { + const allProjects = this.getAllProjects(); + const filteredProjects = new Map(); + const pkgJsonPaths = Array.from(allProjects.values()).map(p => p.packageJsonLocation); + const filteredPkgJsonGlobs = Object(_config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"])(_objectSpread(_objectSpread({}, options), {}, { + rootPath: this.kibanaProject.path + })).map(g => path__WEBPACK_IMPORTED_MODULE_0___default.a.resolve(g, 'package.json')); + const matchingPkgJsonPaths = multimatch__WEBPACK_IMPORTED_MODULE_1___default()(pkgJsonPaths, filteredPkgJsonGlobs); + for (const project of allProjects.values()) { + const pathMatches = matchingPkgJsonPaths.includes(project.packageJsonLocation); + const notExcluded = !options.exclude.includes(project.name); + const isIncluded = !options.include.length || options.include.includes(project.name); -function tap(nextOrObserver, error, complete) { - return function tapOperatorFunction(source) { - return source.lift(new DoOperator(nextOrObserver, error, complete)); - }; -} -var DoOperator = /*@__PURE__*/ (function () { - function DoOperator(nextOrObserver, error, complete) { - this.nextOrObserver = nextOrObserver; - this.error = error; - this.complete = complete; - } - DoOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TapSubscriber(subscriber, this.nextOrObserver, this.error, this.complete)); - }; - return DoOperator; -}()); -var TapSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TapSubscriber, _super); - function TapSubscriber(destination, observerOrNext, error, complete) { - var _this = _super.call(this, destination) || this; - _this._tapNext = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapError = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapComplete = _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapError = error || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapComplete = complete || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - if (Object(_util_isFunction__WEBPACK_IMPORTED_MODULE_3__["isFunction"])(observerOrNext)) { - _this._context = _this; - _this._tapNext = observerOrNext; - } - else if (observerOrNext) { - _this._context = observerOrNext; - _this._tapNext = observerOrNext.next || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapError = observerOrNext.error || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - _this._tapComplete = observerOrNext.complete || _util_noop__WEBPACK_IMPORTED_MODULE_2__["noop"]; - } - return _this; + if (pathMatches && notExcluded && isIncluded) { + filteredProjects.set(project.name, project); + } } - TapSubscriber.prototype._next = function (value) { - try { - this._tapNext.call(this._context, value); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.next(value); - }; - TapSubscriber.prototype._error = function (err) { - try { - this._tapError.call(this._context, err); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.error(err); - }; - TapSubscriber.prototype._complete = function () { - try { - this._tapComplete.call(this._context); - } - catch (err) { - this.destination.error(err); - return; - } - return this.destination.complete(); - }; - return TapSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=tap.js.map + return filteredProjects; + } + + isPartOfRepo(project) { + return project.path === this.kibanaProject.path || is_path_inside__WEBPACK_IMPORTED_MODULE_2___default()(project.path, this.kibanaProject.path); + } + + isOutsideRepo(project) { + return !this.isPartOfRepo(project); + } + + resolveAllProductionDependencies(yarnLock, log) { + const kibanaDeps = Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_3__["resolveDepsForProject"])({ + project: this.kibanaProject, + yarnLock, + kbn: this, + includeDependentProject: true, + productionDepsOnly: true, + log + }); + const xpackDeps = Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_3__["resolveDepsForProject"])({ + project: this.getProject('x-pack'), + yarnLock, + kbn: this, + includeDependentProject: true, + productionDepsOnly: true, + log + }); + return new Map([...kibanaDeps.entries(), ...xpackDeps.entries()]); + } + +} /***/ }), -/* 474 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 503 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__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 */ +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); + patterns = arrify(patterns); -var defaultThrottleConfig = { - leading: true, - trailing: false + if (list.length === 0 || patterns.length === 0) { + return []; + } + + return patterns.reduce((result, pattern) => { + let process = arrayUnion; + + if (pattern[0] === '!') { + pattern = pattern.slice(1); + process = arrayDiffer; + } + + return process(result, minimatch.match(list, pattern, options)); + }, []); }; -function throttle(durationSelector, config) { - if (config === void 0) { - config = defaultThrottleConfig; - } - return function (source) { return source.lift(new ThrottleOperator(durationSelector, config.leading, config.trailing)); }; -} -var ThrottleOperator = /*@__PURE__*/ (function () { - function ThrottleOperator(durationSelector, leading, trailing) { - this.durationSelector = durationSelector; - this.leading = leading; - this.trailing = trailing; - } - ThrottleOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ThrottleSubscriber(subscriber, this.durationSelector, this.leading, this.trailing)); - }; - return ThrottleOperator; -}()); -var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrottleSubscriber, _super); - function ThrottleSubscriber(destination, durationSelector, _leading, _trailing) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - _this.durationSelector = durationSelector; - _this._leading = _leading; - _this._trailing = _trailing; - _this._hasValue = false; - return _this; - } - ThrottleSubscriber.prototype._next = function (value) { - this._hasValue = true; - this._sendValue = value; - if (!this._throttled) { - if (this._leading) { - this.send(); - } - else { - this.throttle(value); - } - } - }; - ThrottleSubscriber.prototype.send = function () { - var _a = this, _hasValue = _a._hasValue, _sendValue = _a._sendValue; - if (_hasValue) { - this.destination.next(_sendValue); - this.throttle(_sendValue); - } - this._hasValue = false; - this._sendValue = null; - }; - 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)); - } - }; - ThrottleSubscriber.prototype.tryDurationSelector = function (value) { - try { - return this.durationSelector(value); - } - catch (err) { - this.destination.error(err); - return null; - } - }; - ThrottleSubscriber.prototype.throttlingDone = function () { - var _a = this, _throttled = _a._throttled, _trailing = _a._trailing; - if (_throttled) { - _throttled.unsubscribe(); - } - this._throttled = null; - if (_trailing) { - this.send(); - } - }; - ThrottleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.throttlingDone(); - }; - ThrottleSubscriber.prototype.notifyComplete = function () { - this.throttlingDone(); - }; - return ThrottleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=throttle.js.map /***/ }), -/* 475 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 504 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return throttleTime; }); -/* 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__(474); -/** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ +module.exports = (...arguments_) => { + return [...new Set([].concat(...arguments_))]; +}; -function throttleTime(duration, scheduler, config) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; - } - if (config === void 0) { - config = _throttle__WEBPACK_IMPORTED_MODULE_3__["defaultThrottleConfig"]; - } - return function (source) { return source.lift(new ThrottleTimeOperator(duration, scheduler, config.leading, config.trailing)); }; -} -var ThrottleTimeOperator = /*@__PURE__*/ (function () { - function ThrottleTimeOperator(duration, scheduler, leading, trailing) { - this.duration = duration; - this.scheduler = scheduler; - this.leading = leading; - this.trailing = trailing; - } - ThrottleTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new ThrottleTimeSubscriber(subscriber, this.duration, this.scheduler, this.leading, this.trailing)); - }; - return ThrottleTimeOperator; -}()); -var ThrottleTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](ThrottleTimeSubscriber, _super); - function ThrottleTimeSubscriber(destination, duration, scheduler, leading, trailing) { - var _this = _super.call(this, destination) || this; - _this.duration = duration; - _this.scheduler = scheduler; - _this.leading = leading; - _this.trailing = trailing; - _this._hasTrailingValue = false; - _this._trailingValue = null; - return _this; - } - ThrottleTimeSubscriber.prototype._next = function (value) { - if (this.throttled) { - if (this.trailing) { - this._trailingValue = value; - this._hasTrailingValue = true; - } - } - else { - this.add(this.throttled = this.scheduler.schedule(dispatchNext, this.duration, { subscriber: this })); - if (this.leading) { - this.destination.next(value); - } - else if (this.trailing) { - this._trailingValue = value; - this._hasTrailingValue = true; - } - } - }; - ThrottleTimeSubscriber.prototype._complete = function () { - if (this._hasTrailingValue) { - this.destination.next(this._trailingValue); - this.destination.complete(); - } - else { - this.destination.complete(); - } - }; - ThrottleTimeSubscriber.prototype.clearThrottle = function () { - var throttled = this.throttled; - if (throttled) { - if (this.trailing && this._hasTrailingValue) { - this.destination.next(this._trailingValue); - this._trailingValue = null; - this._hasTrailingValue = false; - } - throttled.unsubscribe(); - this.remove(throttled); - this.throttled = null; - } - }; - return ThrottleTimeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -function dispatchNext(arg) { - var subscriber = arg.subscriber; - subscriber.clearThrottle(); -} -//# sourceMappingURL=throttleTime.js.map +/***/ }), +/* 505 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +const arrayDiffer = (array, ...values) => { + const rest = new Set([].concat(...values)); + return array.filter(element => !rest.has(element)); +}; + +module.exports = arrayDiffer; /***/ }), -/* 476 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 506 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__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__(436); -/* harmony import */ var _observable_defer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66); -/** PURE_IMPORTS_START _scheduler_async,_scan,_observable_defer,_map PURE_IMPORTS_END */ +const arrify = value => { + if (value === null || value === undefined) { + return []; + } + if (Array.isArray(value)) { + return value; + } -function timeInterval(scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; - } - return function (source) { - return Object(_observable_defer__WEBPACK_IMPORTED_MODULE_2__["defer"])(function () { - return source.pipe(Object(_scan__WEBPACK_IMPORTED_MODULE_1__["scan"])(function (_a, value) { - var current = _a.current; - return ({ value: value, current: scheduler.now(), last: current }); - }, { current: scheduler.now(), value: undefined, last: undefined }), Object(_map__WEBPACK_IMPORTED_MODULE_3__["map"])(function (_a) { - var current = _a.current, last = _a.last, value = _a.value; - return new TimeInterval(value, current - last); - })); - }); - }; -} -var TimeInterval = /*@__PURE__*/ (function () { - function TimeInterval(value, interval) { - this.value = value; - this.interval = interval; - } - return TimeInterval; -}()); + if (typeof value === 'string') { + return [value]; + } -//# sourceMappingURL=timeInterval.js.map + if (typeof value[Symbol.iterator] === 'function') { + return [...value]; + } + + return [value]; +}; + +module.exports = arrify; /***/ }), -/* 477 */ +/* 507 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __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__(478); -/* 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 */ - - - +/* 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"]; }); -function timeout(due, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; - } - return Object(_timeoutWith__WEBPACK_IMPORTED_MODULE_2__["timeoutWith"])(due, Object(_observable_throwError__WEBPACK_IMPORTED_MODULE_3__["throwError"])(new _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__["TimeoutError"]()), scheduler); -} -//# sourceMappingURL=timeout.js.map +/* + * 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. + */ /***/ }), -/* 478 */ +/* 508 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __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__(410); -/* 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 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. + */ -function timeoutWith(due, withObservable, scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_1__["async"]; - } - return function (source) { - var absoluteTimeout = Object(_util_isDate__WEBPACK_IMPORTED_MODULE_2__["isDate"])(due); - var waitFor = absoluteTimeout ? (+due - scheduler.now()) : Math.abs(due); - return source.lift(new TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler)); - }; -} -var TimeoutWithOperator = /*@__PURE__*/ (function () { - function TimeoutWithOperator(waitFor, absoluteTimeout, withObservable, scheduler) { - this.waitFor = waitFor; - this.absoluteTimeout = absoluteTimeout; - this.withObservable = withObservable; - this.scheduler = scheduler; - } - TimeoutWithOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new TimeoutWithSubscriber(subscriber, this.absoluteTimeout, this.waitFor, this.withObservable, this.scheduler)); - }; - return TimeoutWithOperator; -}()); -var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](TimeoutWithSubscriber, _super); - function TimeoutWithSubscriber(destination, absoluteTimeout, waitFor, withObservable, scheduler) { - var _this = _super.call(this, destination) || this; - _this.absoluteTimeout = absoluteTimeout; - _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)); - }; - TimeoutWithSubscriber.prototype.scheduleTimeout = function () { - var action = this.action; - if (action) { - this.action = action.schedule(this, this.waitFor); - } - else { - this.add(this.action = this.scheduler.schedule(TimeoutWithSubscriber.dispatchTimeout, this.waitFor, this)); - } - }; - TimeoutWithSubscriber.prototype._next = function (value) { - if (!this.absoluteTimeout) { - this.scheduleTimeout(); - } - _super.prototype._next.call(this, value); - }; - TimeoutWithSubscriber.prototype._unsubscribe = function () { - this.action = null; - this.scheduler = null; - this.withObservable = null; - }; - return TimeoutWithSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -//# sourceMappingURL=timeoutWith.js.map -/***/ }), -/* 479 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return timestamp; }); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Timestamp", function() { return Timestamp; }); -/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(66); -/** PURE_IMPORTS_START _scheduler_async,_map PURE_IMPORTS_END */ +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(', ')}]`); -function timestamp(scheduler) { - if (scheduler === void 0) { - scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__["async"]; + for (const batch of batchedProjects) { + for (const project of batch) { + await deleteTarget(project); + await buildProject(project); + await copyToBuild(project, kibanaRoot, buildRoot); } - return Object(_map__WEBPACK_IMPORTED_MODULE_1__["map"])(function (value) { return new Timestamp(value, scheduler.now()); }); + } } -var Timestamp = /*@__PURE__*/ (function () { - function Timestamp(value, timestamp) { - this.value = value; - this.timestamp = timestamp; - } - return Timestamp; -}()); +/** + * 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. + */ -//# sourceMappingURL=timestamp.js.map +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')); + } -/***/ }), -/* 480 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + const productionProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["includeTransitiveProjects"])(projectsSubset, projects, { + onlyProductionDependencies: true + }); // We remove Kibana, as we're already building Kibana -"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__(435); -/** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ + productionProjects.delete('kibana'); -function toArrayReducer(arr, item, index) { - if (index === 0) { - return [item]; - } - arr.push(item); - return arr; + if (onlyOSS) { + productionProjects.forEach(project => { + if (project.getBuildConfig().oss === false) { + productionProjects.delete(project.json.name); + } + }); + } + + return productionProjects; } -function toArray() { - return Object(_reduce__WEBPACK_IMPORTED_MODULE_0__["reduce"])(toArrayReducer, []); + +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 + }); + } } -//# sourceMappingURL=toArray.js.map +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); +} /***/ }), -/* 481 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 509 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__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 */ +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); -function window(windowBoundaries) { - return function windowOperatorFunction(source) { - return source.lift(new WindowOperator(windowBoundaries)); - }; -} -var WindowOperator = /*@__PURE__*/ (function () { - function WindowOperator(windowBoundaries) { - this.windowBoundaries = windowBoundaries; - } - WindowOperator.prototype.call = function (subscriber, source) { - 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)); - } - return sourceSubscription; - }; - return WindowOperator; -}()); -var WindowSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowSubscriber, _super); - function WindowSubscriber(destination) { - var _this = _super.call(this, destination) || this; - _this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - destination.next(_this.window); - return _this; - } - WindowSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.openWindow(); - }; - WindowSubscriber.prototype.notifyError = function (error, innerSub) { - this._error(error); - }; - WindowSubscriber.prototype.notifyComplete = function (innerSub) { - this._complete(); - }; - WindowSubscriber.prototype._next = function (value) { - this.window.next(value); - }; - WindowSubscriber.prototype._error = function (err) { - this.window.error(err); - this.destination.error(err); - }; - WindowSubscriber.prototype._complete = function () { - this.window.complete(); - this.destination.complete(); - }; - WindowSubscriber.prototype._unsubscribe = function () { - this.window = null; - }; - WindowSubscriber.prototype.openWindow = function () { - var prevWindow = this.window; - if (prevWindow) { - prevWindow.complete(); - } - var destination = this.destination; - var newWindow = this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - destination.next(newWindow); - }; - return WindowSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=window.js.map + 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); + } -/***/ }), -/* 482 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + if (options.parents) { + return path.join(destination, dirname, basename); + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return windowCount; }); -/* 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 _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27); -/** PURE_IMPORTS_START tslib,_Subscriber,_Subject PURE_IMPORTS_END */ + return path.join(destination, basename); +}; +module.exports = (source, destination, { + concurrency = (os.cpus().length || 1) * 2, + ...options +} = {}) => { + const progressEmitter = new EventEmitter(); + options = { + ...defaultOptions, + ...options + }; -function windowCount(windowSize, startWindowEvery) { - if (startWindowEvery === void 0) { - startWindowEvery = 0; - } - return function windowCountOperatorFunction(source) { - return source.lift(new WindowCountOperator(windowSize, startWindowEvery)); - }; -} -var WindowCountOperator = /*@__PURE__*/ (function () { - function WindowCountOperator(windowSize, startWindowEvery) { - this.windowSize = windowSize; - this.startWindowEvery = startWindowEvery; - } - WindowCountOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WindowCountSubscriber(subscriber, this.windowSize, this.startWindowEvery)); - }; - return WindowCountOperator; -}()); -var WindowCountSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowCountSubscriber, _super); - function WindowCountSubscriber(destination, windowSize, startWindowEvery) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - _this.windowSize = windowSize; - _this.startWindowEvery = startWindowEvery; - _this.windows = [new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"]()]; - _this.count = 0; - destination.next(_this.windows[0]); - return _this; - } - WindowCountSubscriber.prototype._next = function (value) { - var startWindowEvery = (this.startWindowEvery > 0) ? this.startWindowEvery : this.windowSize; - var destination = this.destination; - var windowSize = this.windowSize; - var windows = this.windows; - var len = windows.length; - for (var i = 0; i < len && !this.closed; i++) { - windows[i].next(value); - } - var c = this.count - windowSize + 1; - if (c >= 0 && c % startWindowEvery === 0 && !this.closed) { - windows.shift().complete(); - } - if (++this.count % startWindowEvery === 0 && !this.closed) { - var window_1 = new _Subject__WEBPACK_IMPORTED_MODULE_2__["Subject"](); - windows.push(window_1); - destination.next(window_1); - } - }; - WindowCountSubscriber.prototype._error = function (err) { - var windows = this.windows; - if (windows) { - while (windows.length > 0 && !this.closed) { - windows.shift().error(err); - } - } - this.destination.error(err); - }; - WindowCountSubscriber.prototype._complete = function () { - var windows = this.windows; - if (windows) { - while (windows.length > 0 && !this.closed) { - windows.shift().complete(); - } - } - this.destination.complete(); - }; - WindowCountSubscriber.prototype._unsubscribe = function () { - this.count = 0; - this.windows = null; - }; - return WindowCountSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_1__["Subscriber"])); -//# sourceMappingURL=windowCount.js.map + 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`); + } -/***/ }), -/* 483 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + const fileProgressHandler = event => { + const fileStatus = copyStatus.get(event.src) || {written: 0, percent: 0}; -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return windowTime; }); -/* 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 _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_isScheduler__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(45); -/** PURE_IMPORTS_START tslib,_Subject,_scheduler_async,_Subscriber,_util_isNumeric,_util_isScheduler PURE_IMPORTS_END */ + 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); + } -function windowTime(windowTimeSpan) { - var scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_2__["async"]; - var windowCreationInterval = null; - var maxWindowSize = Number.POSITIVE_INFINITY; - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[3])) { - scheduler = arguments[3]; - } - if (Object(_util_isScheduler__WEBPACK_IMPORTED_MODULE_5__["isScheduler"])(arguments[2])) { - scheduler = arguments[2]; - } - else if (Object(_util_isNumeric__WEBPACK_IMPORTED_MODULE_4__["isNumeric"])(arguments[2])) { - maxWindowSize = 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]; - } - return function windowTimeOperatorFunction(source) { - return source.lift(new WindowTimeOperator(windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler)); - }; -} -var WindowTimeOperator = /*@__PURE__*/ (function () { - function WindowTimeOperator(windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler) { - this.windowTimeSpan = windowTimeSpan; - this.windowCreationInterval = windowCreationInterval; - this.maxWindowSize = maxWindowSize; - this.scheduler = scheduler; - } - WindowTimeOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WindowTimeSubscriber(subscriber, this.windowTimeSpan, this.windowCreationInterval, this.maxWindowSize, this.scheduler)); - }; - return WindowTimeOperator; -}()); -var CountedSubject = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](CountedSubject, _super); - function CountedSubject() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this._numberOfNextedValues = 0; - return _this; - } - CountedSubject.prototype.next = function (value) { - this._numberOfNextedValues++; - _super.prototype.next.call(this, value); - }; - Object.defineProperty(CountedSubject.prototype, "numberOfNextedValues", { - get: function () { - return this._numberOfNextedValues; - }, - enumerable: true, - configurable: true - }); - return CountedSubject; -}(_Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"])); -var WindowTimeSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowTimeSubscriber, _super); - function WindowTimeSubscriber(destination, windowTimeSpan, windowCreationInterval, maxWindowSize, scheduler) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - _this.windowTimeSpan = windowTimeSpan; - _this.windowCreationInterval = windowCreationInterval; - _this.maxWindowSize = maxWindowSize; - _this.scheduler = scheduler; - _this.windows = []; - var window = _this.openWindow(); - if (windowCreationInterval !== null && windowCreationInterval >= 0) { - var closeState = { subscriber: _this, window: window, context: null }; - var creationState = { windowTimeSpan: windowTimeSpan, windowCreationInterval: windowCreationInterval, subscriber: _this, scheduler: scheduler }; - _this.add(scheduler.schedule(dispatchWindowClose, windowTimeSpan, closeState)); - _this.add(scheduler.schedule(dispatchWindowCreation, windowCreationInterval, creationState)); - } - else { - var timeSpanOnlyState = { subscriber: _this, window: window, windowTimeSpan: windowTimeSpan }; - _this.add(scheduler.schedule(dispatchWindowTimeSpanOnly, windowTimeSpan, timeSpanOnlyState)); - } - return _this; - } - WindowTimeSubscriber.prototype._next = function (value) { - var windows = this.windows; - var len = windows.length; - for (var i = 0; i < len; i++) { - var window_1 = windows[i]; - if (!window_1.closed) { - window_1.next(value); - if (window_1.numberOfNextedValues >= this.maxWindowSize) { - this.closeWindow(window_1); - } - } - } - }; - WindowTimeSubscriber.prototype._error = function (err) { - var windows = this.windows; - while (windows.length > 0) { - windows.shift().error(err); - } - this.destination.error(err); - }; - WindowTimeSubscriber.prototype._complete = function () { - var windows = this.windows; - while (windows.length > 0) { - var window_2 = windows.shift(); - if (!window_2.closed) { - window_2.complete(); - } - } - this.destination.complete(); - }; - WindowTimeSubscriber.prototype.openWindow = function () { - var window = new CountedSubject(); - this.windows.push(window); - var destination = this.destination; - destination.next(window); - return window; - }; - WindowTimeSubscriber.prototype.closeWindow = function (window) { - window.complete(); - var windows = this.windows; - windows.splice(windows.indexOf(window), 1); - }; - return WindowTimeSubscriber; -}(_Subscriber__WEBPACK_IMPORTED_MODULE_3__["Subscriber"])); -function dispatchWindowTimeSpanOnly(state) { - var subscriber = state.subscriber, windowTimeSpan = state.windowTimeSpan, window = state.window; - if (window) { - subscriber.closeWindow(window); - } - state.window = subscriber.openWindow(); - this.schedule(state, windowTimeSpan); -} -function dispatchWindowCreation(state) { - var windowTimeSpan = state.windowTimeSpan, subscriber = state.subscriber, scheduler = state.scheduler, windowCreationInterval = state.windowCreationInterval; - var window = subscriber.openWindow(); - var action = this; - var context = { action: action, subscription: null }; - var timeSpanState = { subscriber: subscriber, window: window, context: context }; - context.subscription = scheduler.schedule(dispatchWindowClose, windowTimeSpan, timeSpanState); - action.add(context.subscription); - action.schedule(state, windowCreationInterval); -} -function dispatchWindowClose(state) { - var subscriber = state.subscriber, window = state.window, context = state.context; - if (context && context.action && context.subscription) { - context.action.remove(context.subscription); - } - subscriber.closeWindow(window); -} -//# sourceMappingURL=windowTime.js.map + return to; + }; + }), {concurrency}); + })(); + + promise.on = (...arguments_) => { + progressEmitter.on(...arguments_); + return promise; + }; + + return promise; +}; /***/ }), -/* 484 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 510 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return windowToggle; }); -/* 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 _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17); -/* 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,_Subject,_Subscription,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ +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__) { -function windowToggle(openings, closingSelector) { - return function (source) { return source.lift(new WindowToggleOperator(openings, closingSelector)); }; -} -var WindowToggleOperator = /*@__PURE__*/ (function () { - function WindowToggleOperator(openings, closingSelector) { - this.openings = openings; - this.closingSelector = closingSelector; - } - WindowToggleOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WindowToggleSubscriber(subscriber, this.openings, this.closingSelector)); - }; - return WindowToggleOperator; -}()); -var WindowToggleSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowToggleSubscriber, _super); - function WindowToggleSubscriber(destination, openings, closingSelector) { - var _this = _super.call(this, destination) || this; - _this.openings = openings; - _this.closingSelector = closingSelector; - _this.contexts = []; - _this.add(_this.openSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(_this, openings, openings)); - return _this; - } - WindowToggleSubscriber.prototype._next = function (value) { - var contexts = this.contexts; - if (contexts) { - var len = contexts.length; - for (var i = 0; i < len; i++) { - contexts[i].window.next(value); - } - } - }; - WindowToggleSubscriber.prototype._error = function (err) { - var contexts = this.contexts; - this.contexts = null; - if (contexts) { - var len = contexts.length; - var index = -1; - while (++index < len) { - var context_1 = contexts[index]; - context_1.window.error(err); - context_1.subscription.unsubscribe(); - } - } - _super.prototype._error.call(this, err); - }; - WindowToggleSubscriber.prototype._complete = function () { - var contexts = this.contexts; - this.contexts = null; - if (contexts) { - var len = contexts.length; - var index = -1; - while (++index < len) { - var context_2 = contexts[index]; - context_2.window.complete(); - context_2.subscription.unsubscribe(); - } - } - _super.prototype._complete.call(this); - }; - WindowToggleSubscriber.prototype._unsubscribe = function () { - var contexts = this.contexts; - this.contexts = null; - if (contexts) { - var len = contexts.length; - var index = -1; - while (++index < len) { - var context_3 = contexts[index]; - context_3.window.unsubscribe(); - context_3.subscription.unsubscribe(); - } - } - }; - WindowToggleSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - if (outerValue === this.openings) { - var closingNotifier = void 0; - try { - var closingSelector = this.closingSelector; - closingNotifier = closingSelector(innerValue); - } - catch (e) { - return this.error(e); - } - var window_1 = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - var subscription = new _Subscription__WEBPACK_IMPORTED_MODULE_2__["Subscription"](); - var context_4 = { window: window_1, subscription: subscription }; - this.contexts.push(context_4); - var innerSubscription = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__["subscribeToResult"])(this, closingNotifier, context_4); - if (innerSubscription.closed) { - this.closeWindow(this.contexts.length - 1); - } - else { - innerSubscription.context = context_4; - subscription.add(innerSubscription); - } - this.destination.next(window_1); - } - else { - this.closeWindow(this.contexts.indexOf(outerValue)); - } - }; - WindowToggleSubscriber.prototype.notifyError = function (err) { - this.error(err); - }; - WindowToggleSubscriber.prototype.notifyComplete = function (inner) { - if (inner !== this.openSubscription) { - this.closeWindow(this.contexts.indexOf(inner.context)); - } - }; - WindowToggleSubscriber.prototype.closeWindow = function (index) { - if (index === -1) { - return; - } - var contexts = this.contexts; - var context = contexts[index]; - var window = context.window, subscription = context.subscription; - contexts.splice(index, 1); - window.complete(); - subscription.unsubscribe(); - }; - return WindowToggleSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__["OuterSubscriber"])); -//# sourceMappingURL=windowToggle.js.map +"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; /***/ }), -/* 485 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 512 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return windowWhen; }); -/* 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 */ +const arrify = value => { + if (value === null || value === undefined) { + return []; + } + if (Array.isArray(value)) { + return value; + } -function windowWhen(closingSelector) { - return function windowWhenOperatorFunction(source) { - return source.lift(new WindowOperator(closingSelector)); - }; -} -var WindowOperator = /*@__PURE__*/ (function () { - function WindowOperator(closingSelector) { - this.closingSelector = closingSelector; - } - WindowOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WindowSubscriber(subscriber, this.closingSelector)); - }; - return WindowOperator; -}()); -var WindowSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WindowSubscriber, _super); - function WindowSubscriber(destination, closingSelector) { - var _this = _super.call(this, destination) || this; - _this.destination = destination; - _this.closingSelector = closingSelector; - _this.openWindow(); - return _this; - } - WindowSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.openWindow(innerSub); - }; - WindowSubscriber.prototype.notifyError = function (error, innerSub) { - this._error(error); - }; - WindowSubscriber.prototype.notifyComplete = function (innerSub) { - this.openWindow(innerSub); - }; - WindowSubscriber.prototype._next = function (value) { - this.window.next(value); - }; - WindowSubscriber.prototype._error = function (err) { - this.window.error(err); - this.destination.error(err); - this.unsubscribeClosingNotification(); - }; - WindowSubscriber.prototype._complete = function () { - this.window.complete(); - this.destination.complete(); - this.unsubscribeClosingNotification(); - }; - WindowSubscriber.prototype.unsubscribeClosingNotification = function () { - if (this.closingNotification) { - this.closingNotification.unsubscribe(); - } - }; - WindowSubscriber.prototype.openWindow = function (innerSub) { - if (innerSub === void 0) { - innerSub = null; - } - if (innerSub) { - this.remove(innerSub); - innerSub.unsubscribe(); - } - var prevWindow = this.window; - if (prevWindow) { - prevWindow.complete(); - } - var window = this.window = new _Subject__WEBPACK_IMPORTED_MODULE_1__["Subject"](); - this.destination.next(window); - var closingNotifier; - try { - var closingSelector = this.closingSelector; - closingNotifier = closingSelector(); - } - catch (e) { - this.destination.error(e); - this.window.error(e); - return; - } - this.add(this.closingNotification = Object(_util_subscribeToResult__WEBPACK_IMPORTED_MODULE_3__["subscribeToResult"])(this, closingNotifier)); - }; - return WindowSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_2__["OuterSubscriber"])); -//# sourceMappingURL=windowWhen.js.map + if (typeof value === 'string') { + return [value]; + } + + if (typeof value[Symbol.iterator] === 'function') { + return [...value]; + } + + return [value]; +}; + +module.exports = arrify; /***/ }), -/* 486 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 513 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return withLatestFrom; }); -/* 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 */ +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; -function withLatestFrom() { - var args = []; - for (var _i = 0; _i < arguments.length; _i++) { - args[_i] = arguments[_i]; - } - return function (source) { - var project; - if (typeof args[args.length - 1] === 'function') { - project = args.pop(); - } - var observables = args; - return source.lift(new WithLatestFromOperator(observables, project)); - }; -} -var WithLatestFromOperator = /*@__PURE__*/ (function () { - function WithLatestFromOperator(observables, project) { - this.observables = observables; - this.project = project; - } - WithLatestFromOperator.prototype.call = function (subscriber, source) { - return source.subscribe(new WithLatestFromSubscriber(subscriber, this.observables, this.project)); - }; - return WithLatestFromOperator; -}()); -var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { - tslib__WEBPACK_IMPORTED_MODULE_0__["__extends"](WithLatestFromSubscriber, _super); - function WithLatestFromSubscriber(destination, observables, project) { - var _this = _super.call(this, destination) || this; - _this.observables = observables; - _this.project = project; - _this.toRespond = []; - var len = observables.length; - _this.values = new Array(len); - for (var i = 0; i < len; i++) { - _this.toRespond.push(i); - } - 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)); - } - return _this; - } - WithLatestFromSubscriber.prototype.notifyNext = function (outerValue, innerValue, outerIndex, innerIndex, innerSub) { - this.values[outerIndex] = innerValue; - var toRespond = this.toRespond; - if (toRespond.length > 0) { - var found = toRespond.indexOf(outerIndex); - if (found !== -1) { - toRespond.splice(found, 1); - } - } - }; - WithLatestFromSubscriber.prototype.notifyComplete = function () { - }; - WithLatestFromSubscriber.prototype._next = function (value) { - if (this.toRespond.length === 0) { - var args = [value].concat(this.values); - if (this.project) { - this._tryProject(args); - } - else { - this.destination.next(args); - } - } - }; - WithLatestFromSubscriber.prototype._tryProject = function (args) { - var result; - try { - result = this.project.apply(this, args); - } - catch (err) { - this.destination.error(err); - return; - } - this.destination.next(result); - }; - return WithLatestFromSubscriber; -}(_OuterSubscriber__WEBPACK_IMPORTED_MODULE_1__["OuterSubscriber"])); -//# sourceMappingURL=withLatestFrom.js.map +const isNegative = pattern => pattern[0] === '!'; +const assertPatternsInput = patterns => { + if (!patterns.every(x => typeof x === 'string')) { + throw new TypeError('Patterns must be a string or an array of strings'); + } +}; -/***/ }), -/* 487 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +const checkCwdOption = options => { + if (options && options.cwd && !fs.statSync(options.cwd).isDirectory()) { + throw new Error('The `cwd` option must be a path to a directory'); + } +}; -"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); -/** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ +const generateGlobTasks = (patterns, taskOptions) => { + patterns = arrayUnion([].concat(patterns)); + assertPatternsInput(patterns); + checkCwdOption(taskOptions); -function zip() { - var observables = []; - for (var _i = 0; _i < arguments.length; _i++) { - observables[_i] = arguments[_i]; - } - return function zipOperatorFunction(source) { - return source.lift.call(_observable_zip__WEBPACK_IMPORTED_MODULE_0__["zip"].apply(void 0, [source].concat(observables))); - }; -} -//# sourceMappingURL=zip.js.map + const globTasks = []; + taskOptions = Object.assign({ + ignore: [], + expandDirectories: true + }, taskOptions); -/***/ }), -/* 488 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + patterns.forEach((pattern, i) => { + if (isNegative(pattern)) { + return; + } -"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); -/** PURE_IMPORTS_START _observable_zip PURE_IMPORTS_END */ + const ignore = patterns + .slice(i) + .filter(isNegative) + .map(pattern => pattern.slice(1)); -function zipAll(project) { - return function (source) { return source.lift(new _observable_zip__WEBPACK_IMPORTED_MODULE_0__["ZipOperator"](project)); }; -} -//# sourceMappingURL=zipAll.js.map + const options = Object.assign({}, taskOptions, { + ignore: taskOptions.ignore.concat(ignore) + }); + globTasks.push({pattern, options}); + }); -/***/ }), -/* 489 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + return globTasks; +}; -"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__(490); -/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(491); -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; } +const globDirs = (task, fn) => { + let options = {}; + if (task.options.cwd) { + options.cwd = task.options.cwd; + } -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; } + if (Array.isArray(task.options.expandDirectories)) { + options = Object.assign(options, {files: task.options.expandDirectories}); + } else if (typeof task.options.expandDirectories === 'object') { + options = Object.assign(options, task.options.expandDirectories); + } -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; } + return fn(task.pattern, options); +}; -/* - * 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 getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; +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 + }; +}; +const globby = (patterns, options) => { + let globTasks; + try { + globTasks = generateGlobTasks(patterns, options); + } catch (error) { + return Promise.reject(error); + } -async function runCommand(command, config) { - try { - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(`Running [${command.name}] command from [${config.rootPath}]`); - const kbn = await _utils_kibana__WEBPACK_IMPORTED_MODULE_4__["Kibana"].loadFrom(config.rootPath); - const projects = kbn.getFilteredProjects({ - skipKibanaPlugins: Boolean(config.options['skip-kibana-plugins']), - ossOnly: Boolean(config.options.oss), - exclude: toArray(config.options.exclude), - include: toArray(config.options.include) - }); + const getTasks = Promise.all(globTasks.map(task => Promise.resolve(getPattern(task, dirGlob)) + .then(globs => Promise.all(globs.map(globToTask(task)))) + )) + .then(tasks => arrayUnion(...tasks)); - if (projects.size === 0) { - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(`There are no projects found. Double check project name(s) in '-i/--include' and '-e/--exclude' filters.`); - return process.exit(1); - } + const getFilter = () => { + return Promise.resolve( + options && options.gitignore ? + gitignore({cwd: options.cwd, ignore: options.ignore}) : + DEFAULT_FILTER + ); + }; - const projectGraph = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_2__["buildProjectGraph"])(projects); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(`Found ${projects.size.toString()} projects`); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].debug(Object(_utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__["renderProjectsTree"])(config.rootPath, projects)); - await command.run(projects, projectGraph, _objectSpread(_objectSpread({}, config), {}, { - kbn - })); - } catch (error) { - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(`[${command.name}] failed:`); + return getFilter() + .then(filter => { + return getTasks + .then(tasks => Promise.all(tasks.map(task => fastGlob(task.pattern, task.options)))) + .then(paths => arrayUnion(...paths)) + .then(paths => paths.filter(p => !filter(p))); + }); +}; - if (error instanceof _utils_errors__WEBPACK_IMPORTED_MODULE_0__["CliError"]) { - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(error.message); - const metaOutput = Object.entries(error.meta).map(([key, value]) => `${key}: ${value}`).join('\n'); +module.exports = globby; +// TODO: Remove this for the next major release +module.exports.default = globby; - if (metaOutput) { - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info('Additional debugging info:\n'); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].indent(2); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].info(metaOutput); - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].indent(-2); - } - } else { - _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].error(error); - } +module.exports.sync = (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); - process.exit(1); - } -} + const getFilter = () => { + return options && options.gitignore ? + gitignore.sync({cwd: options.cwd, ignore: options.ignore}) : + DEFAULT_FILTER; + }; -function toArray(value) { - if (value == null) { - return []; - } + const tasks = globTasks.reduce((tasks, task) => { + const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); + return tasks.concat(newTask); + }, []); + + const filter = getFilter(); + return tasks.reduce( + (matches, task) => arrayUnion(matches, fastGlob.sync(task.pattern, task.options)), + [] + ).filter(p => !filter(p)); +}; + +module.exports.generateGlobTasks = generateGlobTasks; + +module.exports.hasMagic = (patterns, options) => [] + .concat(patterns) + .some(pattern => glob.hasMagic(pattern, options)); + +module.exports.gitignore = gitignore; - return Array.isArray(value) ? value : [value]; -} /***/ }), -/* 490 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 514 */ +/***/ (function(module, 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___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__); -/* - * 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 arrayUniq = __webpack_require__(515); -const projectKey = Symbol('__project'); -function renderProjectsTree(rootPath, projects) { - const projectsTree = buildProjectsTree(rootPath, projects); - return treeToString(createTreeStructure(projectsTree)); +module.exports = function () { + return arrayUniq([].concat.apply([], arguments)); +}; + + +/***/ }), +/* 515 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +// there's 3 implementations written in increasing order of efficiency + +// 1 - no Set type is defined +function uniqNoSet(arr) { + var ret = []; + + for (var i = 0; i < arr.length; i++) { + if (ret.indexOf(arr[i]) === -1) { + ret.push(arr[i]); + } + } + + return ret; } -function treeToString(tree) { - return [tree.name].concat(childrenToStrings(tree.children, '')).join('\n'); +// 2 - a simple Set type is defined +function uniqSet(arr) { + var seen = new Set(); + return arr.filter(function (el) { + if (!seen.has(el)) { + seen.add(el); + return true; + } + + return false; + }); } -function childrenToStrings(tree, treePrefix) { - if (tree === undefined) { - return []; - } +// 3 - a standard Set type is defined and it has a forEach method +function uniqSetWithForEach(arr) { + var ret = []; - let strings = []; - tree.forEach((node, index) => { - const isLastNode = tree.length - 1 === index; - const nodePrefix = isLastNode ? '└── ' : '├── '; - const childPrefix = isLastNode ? ' ' : '│ '; - const childrenPrefix = treePrefix + childPrefix; - strings.push(`${treePrefix}${nodePrefix}${node.name}`); - strings = strings.concat(childrenToStrings(node.children, childrenPrefix)); - }); - return strings; + (new Set(arr)).forEach(function (el) { + ret.push(el); + }); + + return ret; } -function createTreeStructure(tree) { - let name; - const children = []; +// V8 currently has a broken implementation +// https://github.com/joyent/node/issues/8449 +function doesForEachActuallyWork() { + var ret = false; - for (const [dir, project] of tree.entries()) { - // This is a leaf node (aka a project) - if (typeof project === 'string') { - name = chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(project); - continue; - } // If there's only one project and the key indicates it's a leaf node, we - // know that we're at a package folder that contains a package.json, so we - // "inline it" so we don't get unnecessary levels, i.e. we'll just see - // `foo` instead of `foo -> foo`. + (new Set([true])).forEach(function (el) { + ret = el; + }); + return ret === true; +} - if (project.size === 1 && project.has(projectKey)) { - const projectName = project.get(projectKey); - children.push({ - children: [], - name: dirOrProjectName(dir, projectName) - }); - continue; - } +if ('Set' in global) { + if (typeof Set.prototype.forEach === 'function' && doesForEachActuallyWork()) { + module.exports = uniqSetWithForEach; + } else { + module.exports = uniqSet; + } +} else { + module.exports = uniqNoSet; +} - const subtree = createTreeStructure(project); // If the name is specified, we know there's a package at the "root" of the - // subtree itself. - if (subtree.name !== undefined) { - const projectName = subtree.name; - children.push({ - children: subtree.children, - name: dirOrProjectName(dir, projectName) - }); - continue; - } // Special-case whenever we have one child, so we don't get unnecessary - // folders in the output. E.g. instead of `foo -> bar -> baz` we get - // `foo/bar/baz` instead. +/***/ }), +/* 516 */ +/***/ (function(module, exports, __webpack_require__) { + +const pkg = __webpack_require__(517); + +module.exports = pkg.async; +module.exports.default = pkg.async; + +module.exports.async = pkg.async; +module.exports.sync = pkg.sync; +module.exports.stream = pkg.stream; + +module.exports.generateTasks = pkg.generateTasks; - if (subtree.children && subtree.children.length === 1) { - const child = subtree.children[0]; - const newName = chalk__WEBPACK_IMPORTED_MODULE_0___default.a.dim(path__WEBPACK_IMPORTED_MODULE_1___default.a.join(dir.toString(), child.name)); - children.push({ - children: child.children, - name: newName - }); - continue; - } +/***/ }), +/* 517 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +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. + */ +function sync(source, opts) { + assertPatternsInput(source); + var works = getWorks(source, reader_sync_1.default, opts); + return arrayUtils.flatten(works); +} +exports.sync = sync; +/** + * Asynchronous API. + */ +function async(source, opts) { + try { + assertPatternsInput(source); + } + catch (error) { + return Promise.reject(error); + } + var works = getWorks(source, reader_async_1.default, opts); + return Promise.all(works).then(arrayUtils.flatten); +} +exports.async = async; +/** + * Stream API. + */ +function stream(source, opts) { + assertPatternsInput(source); + var works = getWorks(source, reader_stream_1.default, opts); + return streamUtils.merge(works); +} +exports.stream = stream; +/** + * Return a set of tasks based on provided patterns. + */ +function generateTasks(source, opts) { + assertPatternsInput(source); + var patterns = [].concat(source); + var options = optionsManager.prepare(opts); + return taskManager.generate(patterns, options); +} +exports.generateTasks = generateTasks; +/** + * Returns a set of works based on provided tasks and class of the reader. + */ +function getWorks(source, _Reader, opts) { + var patterns = [].concat(source); + var options = optionsManager.prepare(opts); + var tasks = taskManager.generate(patterns, options); + var reader = new _Reader(options); + return tasks.map(reader.read, reader); +} +function assertPatternsInput(source) { + if ([].concat(source).every(isString)) { + return; + } + throw new TypeError('Patterns must be a string or an array of strings'); +} +function isString(source) { + /* tslint:disable-next-line strict-type-predicates */ + return typeof source === 'string'; +} + - children.push({ - children: subtree.children, - name: chalk__WEBPACK_IMPORTED_MODULE_0___default.a.dim(dir.toString()) - }); - } +/***/ }), +/* 518 */ +/***/ (function(module, exports, __webpack_require__) { - return { - name, - children - }; -} +"use strict"; + +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +function prepare(options) { + var opts = __assign({ cwd: process.cwd(), deep: true, ignore: [], dot: false, stats: false, onlyFiles: true, onlyDirectories: false, followSymlinkedDirectories: true, unique: true, markDirectories: false, absolute: false, nobrace: false, brace: true, noglobstar: false, globstar: true, noext: false, extension: true, nocase: false, case: true, matchBase: false, transform: null }, options); + if (opts.onlyDirectories) { + opts.onlyFiles = false; + } + opts.brace = !opts.nobrace; + opts.globstar = !opts.noglobstar; + opts.extension = !opts.noext; + opts.case = !opts.nocase; + if (options) { + opts.brace = ('brace' in options ? options.brace : opts.brace); + opts.globstar = ('globstar' in options ? options.globstar : opts.globstar); + opts.extension = ('extension' in options ? options.extension : opts.extension); + opts.case = ('case' in options ? options.case : opts.case); + } + return opts; +} +exports.prepare = prepare; -function dirOrProjectName(dir, projectName) { - return dir === projectName ? chalk__WEBPACK_IMPORTED_MODULE_0___default.a.green(dir) : chalk__WEBPACK_IMPORTED_MODULE_0___default.a`{dim ${dir.toString()} ({reset.green ${projectName}})}`; -} -function buildProjectsTree(rootPath, projects) { - const tree = new Map(); +/***/ }), +/* 519 */ +/***/ (function(module, exports, __webpack_require__) { - for (const project of projects.values()) { - if (rootPath === project.path) { - tree.set(projectKey, project.name); - } else { - const relativeProjectPath = path__WEBPACK_IMPORTED_MODULE_1___default.a.relative(rootPath, project.path); - addProjectToTree(tree, relativeProjectPath.split(path__WEBPACK_IMPORTED_MODULE_1___default.a.sep), project); - } - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var patternUtils = __webpack_require__(520); +/** + * Generate tasks based on parent directory of each pattern. + */ +function generate(patterns, options) { + var unixPatterns = patterns.map(patternUtils.unixifyPattern); + var unixIgnore = options.ignore.map(patternUtils.unixifyPattern); + var positivePatterns = getPositivePatterns(unixPatterns); + var negativePatterns = getNegativePatternsAsPositive(unixPatterns, unixIgnore); + /** + * When the `case` option is disabled, all patterns must be marked as dynamic, because we cannot check filepath + * directly (without read directory). + */ + var staticPatterns = !options.case ? [] : positivePatterns.filter(patternUtils.isStaticPattern); + var dynamicPatterns = !options.case ? positivePatterns : positivePatterns.filter(patternUtils.isDynamicPattern); + var staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false); + var dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true); + return staticTasks.concat(dynamicTasks); +} +exports.generate = generate; +/** + * Convert patterns to tasks based on parent directory of each pattern. + */ +function convertPatternsToTasks(positive, negative, dynamic) { + var 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) { + var task = convertPatternGroupToTask('.', positive, negative, dynamic); + return [task]; + } + return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic); +} +exports.convertPatternsToTasks = convertPatternsToTasks; +/** + * Return only positive patterns. + */ +function getPositivePatterns(patterns) { + return patternUtils.getPositivePatterns(patterns); +} +exports.getPositivePatterns = getPositivePatterns; +/** + * Return only negative patterns. + */ +function getNegativePatternsAsPositive(patterns, ignore) { + var negative = patternUtils.getNegativePatterns(patterns).concat(ignore); + var positive = negative.map(patternUtils.convertToPositivePattern); + return positive; +} +exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; +/** + * Group patterns by base directory of each pattern. + */ +function groupPatternsByBaseDirectory(patterns) { + return patterns.reduce(function (collection, pattern) { + var base = patternUtils.getBaseDirectory(pattern); + if (base in collection) { + collection[base].push(pattern); + } + else { + collection[base] = [pattern]; + } + return collection; + }, {}); +} +exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; +/** + * Convert group of patterns to tasks. + */ +function convertPatternGroupsToTasks(positive, negative, dynamic) { + return Object.keys(positive).map(function (base) { + return convertPatternGroupToTask(base, positive[base], negative, dynamic); + }); +} +exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; +/** + * Create a task for positive and negative patterns. + */ +function convertPatternGroupToTask(base, positive, negative, dynamic) { + return { + base: base, + dynamic: dynamic, + positive: positive, + negative: negative, + patterns: [].concat(positive, negative.map(patternUtils.convertToNegativePattern)) + }; +} +exports.convertPatternGroupToTask = convertPatternGroupToTask; - return tree; -} -function addProjectToTree(tree, pathParts, project) { - if (pathParts.length === 0) { - tree.set(projectKey, project.name); - } else { - const [currentDir, ...rest] = pathParts; +/***/ }), +/* 520 */ +/***/ (function(module, exports, __webpack_require__) { - if (!tree.has(currentDir)) { - tree.set(currentDir, new Map()); - } +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var path = __webpack_require__(4); +var globParent = __webpack_require__(521); +var isGlob = __webpack_require__(294); +var micromatch = __webpack_require__(524); +var GLOBSTAR = '**'; +/** + * Return true for static pattern. + */ +function isStaticPattern(pattern) { + return !isDynamicPattern(pattern); +} +exports.isStaticPattern = isStaticPattern; +/** + * Return true for pattern that looks like glob. + */ +function isDynamicPattern(pattern) { + return isGlob(pattern, { strict: false }); +} +exports.isDynamicPattern = isDynamicPattern; +/** + * Convert a windows «path» to a unix-style «path». + */ +function unixifyPattern(pattern) { + return pattern.replace(/\\/g, '/'); +} +exports.unixifyPattern = unixifyPattern; +/** + * Returns negative pattern as positive pattern. + */ +function convertToPositivePattern(pattern) { + return isNegativePattern(pattern) ? pattern.slice(1) : pattern; +} +exports.convertToPositivePattern = convertToPositivePattern; +/** + * Returns positive pattern as negative pattern. + */ +function convertToNegativePattern(pattern) { + return '!' + pattern; +} +exports.convertToNegativePattern = convertToNegativePattern; +/** + * Return true if provided pattern is negative pattern. + */ +function isNegativePattern(pattern) { + return pattern.startsWith('!') && pattern[1] !== '('; +} +exports.isNegativePattern = isNegativePattern; +/** + * Return true if provided pattern is positive pattern. + */ +function isPositivePattern(pattern) { + return !isNegativePattern(pattern); +} +exports.isPositivePattern = isPositivePattern; +/** + * Extracts negative patterns from array of patterns. + */ +function getNegativePatterns(patterns) { + return patterns.filter(isNegativePattern); +} +exports.getNegativePatterns = getNegativePatterns; +/** + * Extracts positive patterns from array of patterns. + */ +function getPositivePatterns(patterns) { + return patterns.filter(isPositivePattern); +} +exports.getPositivePatterns = getPositivePatterns; +/** + * Extract base directory from provided pattern. + */ +function getBaseDirectory(pattern) { + return globParent(pattern); +} +exports.getBaseDirectory = getBaseDirectory; +/** + * Return true if provided pattern has globstar. + */ +function hasGlobStar(pattern) { + return pattern.indexOf(GLOBSTAR) !== -1; +} +exports.hasGlobStar = hasGlobStar; +/** + * Return true if provided pattern ends with slash and globstar. + */ +function endsWithSlashGlobStar(pattern) { + return pattern.endsWith('/' + GLOBSTAR); +} +exports.endsWithSlashGlobStar = endsWithSlashGlobStar; +/** + * Returns «true» when pattern ends with a slash and globstar or the last partial of the pattern is static pattern. + */ +function isAffectDepthOfReadingPattern(pattern) { + var basename = path.basename(pattern); + return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); +} +exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; +/** + * Return naive depth of provided pattern without depth of the base directory. + */ +function getNaiveDepth(pattern) { + var base = getBaseDirectory(pattern); + var patternDepth = pattern.split('/').length; + var patternBaseDepth = base.split('/').length; + /** + * This is a hack for pattern that has no base directory. + * + * This is related to the `*\something\*` pattern. + */ + if (base === '.') { + return patternDepth - patternBaseDepth; + } + return patternDepth - patternBaseDepth - 1; +} +exports.getNaiveDepth = getNaiveDepth; +/** + * Return max naive depth of provided patterns without depth of the base directory. + */ +function getMaxNaivePatternsDepth(patterns) { + return patterns.reduce(function (max, pattern) { + var depth = getNaiveDepth(pattern); + return depth > max ? depth : max; + }, 0); +} +exports.getMaxNaivePatternsDepth = getMaxNaivePatternsDepth; +/** + * Make RegExp for provided pattern. + */ +function makeRe(pattern, options) { + return micromatch.makeRe(pattern, options); +} +exports.makeRe = makeRe; +/** + * Convert patterns to regexps. + */ +function convertPatternsToRe(patterns, options) { + return patterns.map(function (pattern) { return makeRe(pattern, options); }); +} +exports.convertPatternsToRe = convertPatternsToRe; +/** + * Returns true if the entry match any of the given RegExp's. + */ +function matchAny(entry, patternsRe) { + return patternsRe.some(function (patternRe) { return patternRe.test(entry); }); +} +exports.matchAny = matchAny; - const subtree = tree.get(currentDir); - addProjectToTree(subtree, rest, project); - } -} /***/ }), -/* 491 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { +/* 521 */ +/***/ (function(module, exports, __webpack_require__) { "use strict"; -__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__(492); -/* 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__(366); -/* 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__(279); -/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(145); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(276); -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; } -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; } +var path = __webpack_require__(4); +var isglob = __webpack_require__(522); +var pathDirname = __webpack_require__(523); +var isWin32 = __webpack_require__(121).platform() === 'win32'; -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +module.exports = function globParent(str) { + // flip windows path separators + if (isWin32 && str.indexOf('/') < 0) str = str.split('\\').join('/'); + // special case for strings ending in enclosure containing path separator + if (/[\{\[].*[\/]*.*[\}\]]$/.test(str)) str += '/'; + + // preserves full path in case of trailing path separator + str += 'a'; + // remove path parts that are globby + do {str = pathDirname.posix(str)} + while (isglob(str) || /(^|[^\\])([\{\[]|\([^\)]+$)/.test(str)); + // remove escape chars and return result + return str.replace(/\\([\*\?\|\[\]\(\)\{\}])/g, '$1'); +}; +/***/ }), +/* 522 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Helper class for dealing with a set of projects as children of - * the Kibana project. The kbn/pm is currently implemented to be - * more generic, where everything is an operation of generic projects, - * but that leads to exceptions where we need the kibana project and - * do things like `project.get('kibana')!`. +/*! + * is-glob * - * Using this helper we can restructre the generic list of projects - * as a Kibana object which encapulates all the projects in the - * workspace and knows about the root Kibana project. + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. */ -class Kibana { - static async loadFrom(rootPath) { - return new Kibana(await Object(_projects__WEBPACK_IMPORTED_MODULE_4__["getProjects"])(rootPath, Object(_config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"])({ - rootPath - }))); - } - - constructor(allWorkspaceProjects) { - this.allWorkspaceProjects = allWorkspaceProjects; - - _defineProperty(this, "kibanaProject", void 0); - - const kibanaProject = allWorkspaceProjects.get('kibana'); - - if (!kibanaProject) { - throw new TypeError('Unable to create Kibana object without all projects, including the Kibana project.'); - } +var isExtglob = __webpack_require__(295); - this.kibanaProject = kibanaProject; +module.exports = function isGlob(str) { + if (typeof str !== 'string' || str === '') { + return false; } - /** make an absolute path by resolving subPath relative to the kibana repo */ - - getAbsolute(...subPath) { - return path__WEBPACK_IMPORTED_MODULE_0___default.a.resolve(this.kibanaProject.path, ...subPath); - } - /** convert an absolute path to a relative path, relative to the kibana repo */ + if (isExtglob(str)) return true; + var regex = /(\\).|([*?]|\[.*\]|\{.*\}|\(.*\|.*\)|^!)/; + var match; - getRelative(absolute) { - return path__WEBPACK_IMPORTED_MODULE_0___default.a.relative(this.kibanaProject.path, absolute); + while ((match = regex.exec(str))) { + if (match[2]) return true; + str = str.slice(match.index + match[0].length); } - /** get a copy of the map of all projects in the kibana workspace */ + return false; +}; - getAllProjects() { - return new Map(this.allWorkspaceProjects); - } - /** determine if a project with the given name exists */ +/***/ }), +/* 523 */ +/***/ (function(module, exports, __webpack_require__) { +"use strict"; - hasProject(name) { - return this.allWorkspaceProjects.has(name); - } - /** get a specific project, throws if the name is not known (use hasProject() first) */ +var path = __webpack_require__(4); +var inspect = __webpack_require__(112).inspect; - getProject(name) { - const project = this.allWorkspaceProjects.get(name); +function assertPath(path) { + if (typeof path !== 'string') { + throw new TypeError('Path must be a string. Received ' + inspect(path)); + } +} - if (!project) { - throw new Error(`No package with name "${name}" in the workspace`); +function posix(path) { + assertPath(path); + if (path.length === 0) + return '.'; + var code = path.charCodeAt(0); + var hasRoot = (code === 47/*/*/); + var end = -1; + var matchedSlash = true; + for (var i = path.length - 1; i >= 1; --i) { + code = path.charCodeAt(i); + if (code === 47/*/*/) { + if (!matchedSlash) { + end = i; + break; + } + } else { + // We saw the first non-path separator + matchedSlash = false; } - - return project; } - /** get a project and all of the projects it depends on in a ProjectMap */ + if (end === -1) + return hasRoot ? '/' : '.'; + if (hasRoot && end === 1) + return '//'; + return path.slice(0, end); +} - getProjectAndDeps(name) { - const project = this.getProject(name); - return Object(_projects__WEBPACK_IMPORTED_MODULE_4__["includeTransitiveProjects"])([project], this.allWorkspaceProjects); - } - /** filter the projects to just those matching certain paths/include/exclude tags */ +function win32(path) { + assertPath(path); + var len = path.length; + if (len === 0) + return '.'; + var rootEnd = -1; + var end = -1; + var matchedSlash = true; + var offset = 0; + var code = path.charCodeAt(0); + + // Try to match a root + if (len > 1) { + if (code === 47/*/*/ || code === 92/*\*/) { + // Possible UNC root + rootEnd = offset = 1; - getFilteredProjects(options) { - const allProjects = this.getAllProjects(); - const filteredProjects = new Map(); - const pkgJsonPaths = Array.from(allProjects.values()).map(p => p.packageJsonLocation); - const filteredPkgJsonGlobs = Object(_config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"])(_objectSpread(_objectSpread({}, options), {}, { - rootPath: this.kibanaProject.path - })).map(g => path__WEBPACK_IMPORTED_MODULE_0___default.a.resolve(g, 'package.json')); - const matchingPkgJsonPaths = multimatch__WEBPACK_IMPORTED_MODULE_1___default()(pkgJsonPaths, filteredPkgJsonGlobs); + code = path.charCodeAt(1); + if (code === 47/*/*/ || code === 92/*\*/) { + // Matched double path separator at beginning + var j = 2; + var last = j; + // Match 1 or more non-path separators + for (; j < len; ++j) { + code = path.charCodeAt(j); + if (code === 47/*/*/ || code === 92/*\*/) + break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more path separators + for (; j < len; ++j) { + code = path.charCodeAt(j); + if (code !== 47/*/*/ && code !== 92/*\*/) + break; + } + if (j < len && j !== last) { + // Matched! + last = j; + // Match 1 or more non-path separators + for (; j < len; ++j) { + code = path.charCodeAt(j); + if (code === 47/*/*/ || code === 92/*\*/) + break; + } + if (j === len) { + // We matched a UNC root only + return path; + } + if (j !== last) { + // We matched a UNC root with leftovers - for (const project of allProjects.values()) { - const pathMatches = matchingPkgJsonPaths.includes(project.packageJsonLocation); - const notExcluded = !options.exclude.includes(project.name); - const isIncluded = !options.include.length || options.include.includes(project.name); + // Offset by 1 to include the separator after the UNC root to + // treat it as a "normal root" on top of a (UNC) root + rootEnd = offset = j + 1; + } + } + } + } + } else if ((code >= 65/*A*/ && code <= 90/*Z*/) || + (code >= 97/*a*/ && code <= 122/*z*/)) { + // Possible device root - if (pathMatches && notExcluded && isIncluded) { - filteredProjects.set(project.name, project); + code = path.charCodeAt(1); + if (path.charCodeAt(1) === 58/*:*/) { + rootEnd = offset = 2; + if (len > 2) { + code = path.charCodeAt(2); + if (code === 47/*/*/ || code === 92/*\*/) + rootEnd = offset = 3; + } } } - - return filteredProjects; + } else if (code === 47/*/*/ || code === 92/*\*/) { + return path[0]; } - isPartOfRepo(project) { - return project.path === this.kibanaProject.path || is_path_inside__WEBPACK_IMPORTED_MODULE_2___default()(project.path, this.kibanaProject.path); + for (var i = len - 1; i >= offset; --i) { + code = path.charCodeAt(i); + if (code === 47/*/*/ || code === 92/*\*/) { + if (!matchedSlash) { + end = i; + break; + } + } else { + // We saw the first non-path separator + matchedSlash = false; + } } - isOutsideRepo(project) { - return !this.isPartOfRepo(project); + if (end === -1) { + if (rootEnd === -1) + return '.'; + else + end = rootEnd; } + return path.slice(0, end); +} - resolveAllProductionDependencies(yarnLock, log) { - const kibanaDeps = Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_3__["resolveDepsForProject"])({ - project: this.kibanaProject, - yarnLock, - kbn: this, - includeDependentProject: true, - productionDepsOnly: true, - log - }); - const xpackDeps = Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_3__["resolveDepsForProject"])({ - project: this.getProject('x-pack'), - yarnLock, - kbn: this, - includeDependentProject: true, - productionDepsOnly: true, - log - }); - return new Map([...kibanaDeps.entries(), ...xpackDeps.entries()]); - } +module.exports = process.platform === 'win32' ? win32 : posix; +module.exports.posix = posix; +module.exports.win32 = win32; -} /***/ }), -/* 492 */ +/* 524 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const minimatch = __webpack_require__(149); -const arrayUnion = __webpack_require__(493); -const arrayDiffer = __webpack_require__(494); -const arrify = __webpack_require__(495); - -module.exports = (list, patterns, options = {}) => { - list = arrify(list); - patterns = arrify(patterns); - - if (list.length === 0 || patterns.length === 0) { - return []; - } - - return patterns.reduce((result, pattern) => { - let process = arrayUnion; - if (pattern[0] === '!') { - pattern = pattern.slice(1); - process = arrayDiffer; - } +/** + * Module dependencies + */ - return process(result, minimatch.match(list, pattern, options)); - }, []); -}; +var util = __webpack_require__(112); +var braces = __webpack_require__(525); +var toRegex = __webpack_require__(526); +var extend = __webpack_require__(638); +/** + * Local dependencies + */ -/***/ }), -/* 493 */ -/***/ (function(module, exports, __webpack_require__) { +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; -"use strict"; +/** + * The main function takes a list of strings and one or more + * glob patterns to use for matching. + * + * ```js + * var mm = require('micromatch'); + * mm(list, patterns[, options]); + * + * console.log(mm(['a.js', 'a.txt'], ['*.js'])); + * //=> [ 'a.js' ] + * ``` + * @param {Array} `list` A 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) for changing how matches are performed + * @return {Array} Returns an array of matches + * @summary false + * @api public + */ +function micromatch(list, patterns, options) { + patterns = utils.arrayify(patterns); + list = utils.arrayify(list); -module.exports = (...arguments_) => { - return [...new Set([].concat(...arguments_))]; -}; + var len = patterns.length; + if (list.length === 0 || len === 0) { + return []; + } + if (len === 1) { + return micromatch.match(list, patterns[0], options); + } -/***/ }), -/* 494 */ -/***/ (function(module, exports, __webpack_require__) { + var omit = []; + var keep = []; + var idx = -1; -"use strict"; + while (++idx < len) { + var pattern = patterns[idx]; + if (typeof pattern === 'string' && pattern.charCodeAt(0) === 33 /* ! */) { + omit.push.apply(omit, micromatch.match(list, pattern.slice(1), options)); + } else { + keep.push.apply(keep, micromatch.match(list, pattern, options)); + } + } -const arrayDiffer = (array, ...values) => { - const rest = new Set([].concat(...values)); - return array.filter(element => !rest.has(element)); -}; + var matches = utils.diff(keep, omit); + if (!options || options.nodupes !== false) { + return utils.unique(matches); + } -module.exports = arrayDiffer; + return matches; +} +/** + * Similar to the main function, but `pattern` must be a string. + * + * ```js + * var mm = require('micromatch'); + * mm.match(list, pattern[, options]); + * + * console.log(mm.match(['a.a', 'a.aa', 'a.b', 'a.c'], '*.a')); + * //=> ['a.a', 'a.aa'] + * ``` + * @param {Array} `list` Array of strings to match + * @param {String} `pattern` 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 matches + * @api public + */ -/***/ }), -/* 495 */ -/***/ (function(module, exports, __webpack_require__) { +micromatch.match = function(list, pattern, options) { + if (Array.isArray(pattern)) { + throw new TypeError('expected pattern to be a string'); + } -"use strict"; + var unixify = utils.unixify(options); + var isMatch = memoize('match', pattern, options, micromatch.matcher); + var matches = []; + list = utils.arrayify(list); + var len = list.length; + var idx = -1; -const arrify = value => { - if (value === null || value === undefined) { - return []; - } + while (++idx < len) { + var ele = list[idx]; + if (ele === pattern || isMatch(ele)) { + matches.push(utils.value(ele, unixify, options)); + } + } - if (Array.isArray(value)) { - return value; - } + // if no options were passed, uniquify results and return + if (typeof options === 'undefined') { + return utils.unique(matches); + } - if (typeof value === 'string') { - return [value]; - } + if (matches.length === 0) { + if (options.failglob === true) { + throw new Error('no matches found for "' + pattern + '"'); + } + if (options.nonull === true || options.nullglob === true) { + return [options.unescape ? utils.unescape(pattern) : pattern]; + } + } - if (typeof value[Symbol.iterator] === 'function') { - return [...value]; - } + // if `opts.ignore` was defined, diff ignored list + if (options.ignore) { + matches = micromatch.not(matches, options.ignore, options); + } - return [value]; + return options.nodupes !== false ? utils.unique(matches) : matches; }; -module.exports = arrify; +/** + * Returns true if the specified `string` matches the given glob `pattern`. + * + * ```js + * var mm = require('micromatch'); + * mm.isMatch(string, pattern[, options]); + * + * console.log(mm.isMatch('a.a', '*.a')); + * //=> true + * console.log(mm.isMatch('a.b', '*.a')); + * //=> false + * ``` + * @param {String} `string` String to match + * @param {String} `pattern` 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 string matches the glob pattern. + * @api public + */ +micromatch.isMatch = function(str, pattern, options) { + if (typeof str !== 'string') { + throw new TypeError('expected a string: "' + util.inspect(str) + '"'); + } -/***/ }), -/* 496 */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { + if (isEmptyString(str) || isEmptyString(pattern)) { + return false; + } -"use strict"; -__webpack_require__.r(__webpack_exports__); -/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(497); -/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); + var equals = utils.equalsPattern(options); + if (equals(str)) { + return 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 + var isMatch = memoize('isMatch', pattern, options, micromatch.matcher); + return isMatch(str); +}; + +/** + * Returns true if some of the strings in the given `list` match any of the + * given glob `patterns`. * - * http://www.apache.org/licenses/LICENSE-2.0 + * ```js + * var mm = require('micromatch'); + * mm.some(list, patterns[, options]); * - * 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. + * 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 */ +micromatch.some = function(list, patterns, options) { + if (typeof list === 'string') { + list = [list]; + } + for (var i = 0; i < list.length; i++) { + if (micromatch(list[i], patterns, options).length === 1) { + return true; + } + } + return false; +}; -/***/ }), -/* 497 */ -/***/ (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__(498); -/* 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__(285); -/* 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__(276); -/* 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 +/** + * Returns true if every string in the given `list` matches + * any of the given glob `patterns`. * - * http://www.apache.org/licenses/LICENSE-2.0 + * ```js + * var mm = require('micromatch'); + * mm.every(list, patterns[, options]); * - * 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. + * 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 */ - - - - - - - -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); +micromatch.every = function(list, patterns, options) { + if (typeof list === 'string') { + list = [list]; + } + for (var i = 0; i < list.length; i++) { + if (micromatch(list[i], patterns, options).length !== 1) { + return false; } } -} + return true; +}; + /** - * 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. + * Returns true if **any** of the given glob `patterns` + * match the specified `string`. + * + * ```js + * var mm = require('micromatch'); + * mm.any(string, patterns[, options]); + * + * console.log(mm.any('a.a', ['b.*', '*.a'])); + * //=> true + * console.log(mm.any('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) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public */ -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')]; +micromatch.any = function(str, patterns, options) { + if (typeof str !== 'string') { + throw new TypeError('expected a string: "' + util.inspect(str) + '"'); + } - if (projects.has('x-pack')) { - projectsSubset.push(projects.get('x-pack')); + if (isEmptyString(str) || isEmptyString(patterns)) { + return false; } - const productionProjects = Object(_utils_projects__WEBPACK_IMPORTED_MODULE_7__["includeTransitiveProjects"])(projectsSubset, projects, { - onlyProductionDependencies: true - }); // We remove Kibana, as we're already building Kibana + if (typeof patterns === 'string') { + patterns = [patterns]; + } - productionProjects.delete('kibana'); + for (var i = 0; i < patterns.length; i++) { + if (micromatch.isMatch(str, patterns[i], options)) { + return true; + } + } + return false; +}; + +/** + * Returns true if **all** of the given `patterns` match + * the specified string. + * + * ```js + * var 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 (onlyOSS) { - productionProjects.forEach(project => { - if (project.getBuildConfig().oss === false) { - productionProjects.delete(project.json.name); - } - }); +micromatch.all = function(str, patterns, options) { + if (typeof str !== 'string') { + throw new TypeError('expected a string: "' + util.inspect(str) + '"'); } - - 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 - }); + if (typeof patterns === 'string') { + patterns = [patterns]; } -} - -async function buildProject(project) { - if (project.hasScript('build')) { - await project.runScript('build'); + for (var i = 0; i < patterns.length; i++) { + if (!micromatch.isMatch(str, patterns[i], options)) { + return false; + } } -} + return true; +}; + /** - * 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`. + * Returns a list of strings that _**do not match any**_ of the given `patterns`. * - * 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. + * ```js + * var 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 */ +micromatch.not = function(list, patterns, options) { + var opts = extend({}, options); + var ignore = opts.ignore; + delete opts.ignore; -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); -} - -/***/ }), -/* 498 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; + var unixify = utils.unixify(opts); + list = utils.arrayify(list).map(unixify); -const EventEmitter = __webpack_require__(155); -const path = __webpack_require__(4); -const os = __webpack_require__(120); -const pAll = __webpack_require__(499); -const arrify = __webpack_require__(501); -const globby = __webpack_require__(502); -const isGlob = __webpack_require__(700); -const cpFile = __webpack_require__(701); -const junk = __webpack_require__(713); -const CpyError = __webpack_require__(714); + var matches = utils.diff(list, micromatch(list, patterns, opts)); + if (ignore) { + matches = utils.diff(matches, micromatch(list, ignore)); + } -const defaultOptions = { - ignoreJunk: true + return opts.nodupes !== false ? utils.unique(matches) : matches; }; -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); +/** + * 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 + */ - if (typeof options.rename === 'string') { - basename = options.rename; - } else if (typeof options.rename === 'function') { - basename = options.rename(basename); - } +micromatch.contains = function(str, patterns, options) { + if (typeof str !== 'string') { + throw new TypeError('expected a string: "' + util.inspect(str) + '"'); + } - if (options.cwd) { - destination = path.resolve(options.cwd, destination); - } + if (typeof patterns === 'string') { + if (isEmptyString(str) || isEmptyString(patterns)) { + return false; + } - if (options.parents) { - return path.join(destination, dirname, basename); - } + var equals = utils.equalsPattern(patterns, options); + if (equals(str)) { + return true; + } + var contains = utils.containsPattern(patterns, options); + if (contains(str)) { + return true; + } + } - return path.join(destination, basename); + var opts = extend({}, options, {contains: true}); + return micromatch.any(str, patterns, opts); }; -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; +/** + * Returns true if the given pattern and options should enable + * the `matchBase` option. + * @return {Boolean} + * @api private + */ - let files; - try { - files = await globby(source, options); +micromatch.matchBase = function(pattern, options) { + if (pattern && pattern.indexOf('/') !== -1 || !options) return false; + return options.basename === true || options.matchBase === true; +}; - if (options.ignoreJunk) { - files = files.filter(file => junk.not(path.basename(file))); - } - } catch (error) { - throw new CpyError(`Cannot glob \`${source}\`: ${error.message}`, error); - } +/** + * 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 + * var mm = require('micromatch'); + * mm.matchKeys(object, patterns[, options]); + * + * var 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 + */ - const sourcePaths = source.filter(value => !isGlob(value)); +micromatch.matchKeys = function(obj, patterns, options) { + if (!utils.isObject(obj)) { + throw new TypeError('expected the first argument to be an object'); + } + var keys = micromatch(Object.keys(obj), patterns, options); + return utils.pick(obj, keys); +}; - if (files.length === 0 || (sourcePaths.length > 0 && !sourcePaths.every(value => files.includes(value)))) { - throw new CpyError(`Cannot copy \`${source}\`: the file doesn't exist`); - } +/** + * Returns a memoized 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 + * var mm = require('micromatch'); + * mm.matcher(pattern[, options]); + * + * var isMatch = mm.matcher('*.!(*a)'); + * console.log(isMatch('a.a')); + * //=> false + * console.log(isMatch('a.b')); + * //=> true + * ``` + * @param {String} `pattern` Glob pattern + * @param {Object} `options` See available [options](#options) for changing how matches are performed. + * @return {Function} Returns a matcher function. + * @api public + */ - const fileProgressHandler = event => { - const fileStatus = copyStatus.get(event.src) || {written: 0, percent: 0}; +micromatch.matcher = function matcher(pattern, options) { + if (Array.isArray(pattern)) { + return compose(pattern, options, matcher); + } - if (fileStatus.written !== event.written || fileStatus.percent !== event.percent) { - completedSize -= fileStatus.written; - completedSize += event.written; + // if pattern is a regex + if (pattern instanceof RegExp) { + return test(pattern); + } - if (event.percent === 1 && fileStatus.percent !== 1) { - completedFiles++; - } + // if pattern is invalid + if (!utils.isString(pattern)) { + throw new TypeError('expected pattern to be an array, string or regex'); + } - copyStatus.set(event.src, { - written: event.written, - percent: event.percent - }); + // if pattern is a non-glob string + if (!utils.hasSpecialChars(pattern)) { + if (options && options.nocase === true) { + pattern = pattern.toLowerCase(); + } + return utils.matchPath(pattern, options); + } - progressEmitter.emit('progress', { - totalFiles: files.length, - percent: completedFiles / files.length, - completedFiles, - completedSize - }); - } - }; + // if pattern is a glob string + var re = micromatch.makeRe(pattern, options); - return pAll(files.map(sourcePath => { - return async () => { - const from = preprocessSourcePath(sourcePath, options); - const to = preprocessDestinationPath(sourcePath, destination, options); + // if `options.matchBase` or `options.basename` is defined + if (micromatch.matchBase(pattern, options)) { + return utils.matchBasename(re, options); + } - try { - await cpFile(from, to, options).on('progress', fileProgressHandler); - } catch (error) { - throw new CpyError(`Cannot copy from \`${from}\` to \`${to}\`: ${error.message}`, error); - } + function test(regex) { + var equals = utils.equalsPattern(options); + var unixify = utils.unixify(options); - return to; - }; - }), {concurrency}); - })(); + return function(str) { + if (equals(str)) { + return true; + } - promise.on = (...arguments_) => { - progressEmitter.on(...arguments_); - return promise; - }; + if (regex.test(unixify(str))) { + return true; + } + return false; + }; + } - return promise; + var fn = test(re); + Object.defineProperty(fn, 'result', { + configurable: true, + enumerable: false, + value: re.result + }); + return fn; }; +/** + * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. + * + * ```js + * var 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} `pattern` Glob pattern to use for matching. + * @param {String} `string` 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 string matches the glob pattern, otherwise `null`. + * @api public + */ -/***/ }), -/* 499 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -const pMap = __webpack_require__(500); - -module.exports = (iterable, options) => pMap(iterable, element => element(), options); -// TODO: Remove this for the next major release -module.exports.default = module.exports; - +micromatch.capture = function(pattern, str, options) { + var re = micromatch.makeRe(pattern, extend({capture: true}, options)); + var unixify = utils.unixify(options); -/***/ }), -/* 500 */ -/***/ (function(module, exports, __webpack_require__) { + function match() { + return function(string) { + var match = re.exec(unixify(string)); + if (!match) { + return null; + } -"use strict"; + return match.slice(1); + }; + } + var capture = memoize('capture', pattern, options, match); + return capture(str); +}; -const pMap = (iterable, mapper, options) => new Promise((resolve, reject) => { - options = Object.assign({ - concurrency: Infinity - }, options); +/** + * Create a regular expression from the given glob `pattern`. + * + * ```js + * var 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` See available [options](#options) for changing how matches are performed. + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ - if (typeof mapper !== 'function') { - throw new TypeError('Mapper function is required'); - } +micromatch.makeRe = function(pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('expected pattern to be a string'); + } - const {concurrency} = options; + if (pattern.length > MAX_LENGTH) { + throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); + } - if (!(typeof concurrency === 'number' && concurrency >= 1)) { - throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${concurrency}\` (${typeof concurrency})`); - } + function makeRe() { + var result = micromatch.create(pattern, options); + var ast_array = []; + var output = result.map(function(obj) { + obj.ast.state = obj.state; + ast_array.push(obj.ast); + return obj.output; + }); - const ret = []; - const iterator = iterable[Symbol.iterator](); - let isRejected = false; - let isIterableDone = false; - let resolvingCount = 0; - let currentIndex = 0; + var regex = toRegex(output.join('|'), options); + Object.defineProperty(regex, 'result', { + configurable: true, + enumerable: false, + value: ast_array + }); + return regex; + } - const next = () => { - if (isRejected) { - return; - } + return memoize('makeRe', pattern, options, makeRe); +}; - const nextItem = iterator.next(); - const i = currentIndex; - currentIndex++; +/** + * Expand the given brace `pattern`. + * + * ```js + * var mm = require('micromatch'); + * console.log(mm.braces('foo/{a,b}/bar')); + * //=> ['foo/(a|b)/bar'] + * + * console.log(mm.braces('foo/{a,b}/bar', {expand: true})); + * //=> ['foo/(a|b)/bar'] + * ``` + * @param {String} `pattern` String with brace pattern to expand. + * @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 (nextItem.done) { - isIterableDone = true; +micromatch.braces = function(pattern, options) { + if (typeof pattern !== 'string' && !Array.isArray(pattern)) { + throw new TypeError('expected pattern to be an array or string'); + } - if (resolvingCount === 0) { - resolve(ret); - } + function expand() { + if (options && options.nobrace === true || !/\{.*\}/.test(pattern)) { + return utils.arrayify(pattern); + } + return braces(pattern, options); + } - return; - } + return memoize('braces', pattern, options, expand); +}; - resolvingCount++; +/** + * Proxy to the [micromatch.braces](#method), for parity with + * minimatch. + */ - Promise.resolve(nextItem.value) - .then(element => mapper(element, i)) - .then( - value => { - ret[i] = value; - resolvingCount--; - next(); - }, - error => { - isRejected = true; - reject(error); - } - ); - }; +micromatch.braceExpand = function(pattern, options) { + var opts = extend({}, options, {expand: true}); + return micromatch.braces(pattern, opts); +}; - for (let i = 0; i < concurrency; i++) { - next(); +/** + * Parses the given glob `pattern` and returns an array of abstract syntax + * trees (ASTs), with the compiled `output` and optional source `map` on + * each AST. + * + * ```js + * var mm = require('micromatch'); + * mm.create(pattern[, options]); + * + * console.log(mm.create('abc/*.js')); + * // [{ options: { source: 'string', sourcemap: true }, + * // state: {}, + * // compilers: + * // { ... }, + * // output: '(\\.[\\\\\\/])?abc\\/(?!\\.)(?=.)[^\\/]*?\\.js', + * // ast: + * // { type: 'root', + * // errors: [], + * // nodes: + * // [ ... ], + * // dot: false, + * // input: 'abc/*.js' }, + * // parsingErrors: [], + * // map: + * // { version: 3, + * // sources: [ 'string' ], + * // names: [], + * // mappings: 'AAAA,GAAG,EAAC,kBAAC,EAAC,EAAE', + * // sourcesContent: [ 'abc/*.js' ] }, + * // position: { line: 1, column: 28 }, + * // content: {}, + * // files: {}, + * // idx: 6 }] + * ``` + * @param {String} `pattern` Glob pattern to parse and compile. + * @param {Object} `options` Any [options](#options) to change how parsing and compiling is performed. + * @return {Object} Returns an object with the parsed AST, compiled string and optional source map. + * @api public + */ - if (isIterableDone) { - break; - } - } -}); +micromatch.create = function(pattern, options) { + return memoize('create', pattern, options, function() { + function create(str, opts) { + return micromatch.compile(micromatch.parse(str, opts), opts); + } -module.exports = pMap; -// TODO: Remove this for the next major release -module.exports.default = pMap; + pattern = micromatch.braces(pattern, options); + var len = pattern.length; + var idx = -1; + var res = []; + while (++idx < len) { + res.push(create(pattern[idx], options)); + } + return res; + }); +}; -/***/ }), -/* 501 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Parse the given `str` with the given `options`. + * + * ```js + * var mm = require('micromatch'); + * mm.parse(pattern[, options]); + * + * var ast = mm.parse('a/{b,c}/d'); + * console.log(ast); + * // { type: 'root', + * // errors: [], + * // input: 'a/{b,c}/d', + * // nodes: + * // [ { type: 'bos', val: '' }, + * // { type: 'text', val: 'a/' }, + * // { type: 'brace', + * // nodes: + * // [ { type: 'brace.open', val: '{' }, + * // { type: 'text', val: 'b,c' }, + * // { type: 'brace.close', val: '}' } ] }, + * // { type: 'text', val: '/d' }, + * // { type: 'eos', val: '' } ] } + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {Object} Returns an AST + * @api public + */ -"use strict"; +micromatch.parse = function(pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('expected a string'); + } + function parse() { + var snapdragon = utils.instantiate(null, options); + parsers(snapdragon, options); -const arrify = value => { - if (value === null || value === undefined) { - return []; - } + var ast = snapdragon.parse(pattern, options); + utils.define(ast, 'snapdragon', snapdragon); + ast.input = pattern; + return ast; + } - if (Array.isArray(value)) { - return value; - } + return memoize('parse', pattern, options, parse); +}; - if (typeof value === 'string') { - return [value]; - } +/** + * Compile the given `ast` or string with the given `options`. + * + * ```js + * var mm = require('micromatch'); + * mm.compile(ast[, options]); + * + * var ast = mm.parse('a/{b,c}/d'); + * console.log(mm.compile(ast)); + * // { options: { source: 'string' }, + * // state: {}, + * // compilers: + * // { eos: [Function], + * // noop: [Function], + * // bos: [Function], + * // brace: [Function], + * // 'brace.open': [Function], + * // text: [Function], + * // 'brace.close': [Function] }, + * // output: [ 'a/(b|c)/d' ], + * // ast: + * // { ... }, + * // parsingErrors: [] } + * ``` + * @param {Object|String} `ast` + * @param {Object} `options` + * @return {Object} Returns an object that has an `output` property with the compiled string. + * @api public + */ - if (typeof value[Symbol.iterator] === 'function') { - return [...value]; - } +micromatch.compile = function(ast, options) { + if (typeof ast === 'string') { + ast = micromatch.parse(ast, options); + } - return [value]; + return memoize('compile', ast.input, options, function() { + var snapdragon = utils.instantiate(ast, options); + compilers(snapdragon, options); + return snapdragon.compile(ast, options); + }); }; -module.exports = arrify; +/** + * Clear the regex cache. + * + * ```js + * mm.clearCache(); + * ``` + * @api public + */ +micromatch.clearCache = function() { + micromatch.cache.caches = {}; +}; -/***/ }), -/* 502 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Returns true if the given value is effectively an empty string + */ -"use strict"; +function isEmptyString(val) { + return String(val) === '' || String(val) === './'; +} -const fs = __webpack_require__(133); -const arrayUnion = __webpack_require__(503); -const glob = __webpack_require__(146); -const fastGlob = __webpack_require__(505); -const dirGlob = __webpack_require__(693); -const gitignore = __webpack_require__(696); +/** + * Compose a matcher function with the given patterns. + * This allows matcher functions to be compiled once and + * called multiple times. + */ -const DEFAULT_FILTER = () => false; +function compose(patterns, options, matcher) { + var matchers; -const isNegative = pattern => pattern[0] === '!'; + return memoize('compose', String(patterns), options, function() { + return function(file) { + // delay composition until it's invoked the first time, + // after that it won't be called again + if (!matchers) { + matchers = []; + for (var i = 0; i < patterns.length; i++) { + matchers.push(matcher(patterns[i], options)); + } + } -const assertPatternsInput = patterns => { - if (!patterns.every(x => typeof x === 'string')) { - throw new TypeError('Patterns must be a string or an array of strings'); - } -}; + var len = matchers.length; + while (len--) { + if (matchers[len](file) === true) { + return true; + } + } + return false; + }; + }); +} -const checkCwdOption = options => { - if (options && options.cwd && !fs.statSync(options.cwd).isDirectory()) { - throw new Error('The `cwd` option must be a path to a directory'); - } -}; +/** + * Memoize a generated regex or function. A unique key is generated + * from the `type` (usually method name), the `pattern`, and + * user-defined options. + */ -const generateGlobTasks = (patterns, taskOptions) => { - patterns = arrayUnion([].concat(patterns)); - assertPatternsInput(patterns); - checkCwdOption(taskOptions); +function memoize(type, pattern, options, fn) { + var key = utils.createKey(type + '=' + pattern, options); - const globTasks = []; + if (options && options.cache === false) { + return fn(pattern, options); + } - taskOptions = Object.assign({ - ignore: [], - expandDirectories: true - }, taskOptions); + if (cache.has(type, key)) { + return cache.get(type, key); + } - patterns.forEach((pattern, i) => { - if (isNegative(pattern)) { - return; - } + var val = fn(pattern, options); + cache.set(type, key, val); + return val; +} - const ignore = patterns - .slice(i) - .filter(isNegative) - .map(pattern => pattern.slice(1)); +/** + * Expose compiler, parser and cache on `micromatch` + */ - const options = Object.assign({}, taskOptions, { - ignore: taskOptions.ignore.concat(ignore) - }); +micromatch.compilers = compilers; +micromatch.parsers = parsers; +micromatch.caches = cache.caches; - globTasks.push({pattern, options}); - }); +/** + * Expose `micromatch` + * @type {Function} + */ - return globTasks; -}; +module.exports = micromatch; -const globDirs = (task, fn) => { - let options = {}; - if (task.options.cwd) { - options.cwd = task.options.cwd; - } - if (Array.isArray(task.options.expandDirectories)) { - options = Object.assign(options, {files: task.options.expandDirectories}); - } else if (typeof task.options.expandDirectories === 'object') { - options = Object.assign(options, task.options.expandDirectories); - } +/***/ }), +/* 525 */ +/***/ (function(module, exports, __webpack_require__) { - return fn(task.pattern, options); -}; +"use strict"; -const getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; -const globToTask = task => glob => { - const {options} = task; - if (options.ignore && Array.isArray(options.ignore) && options.expandDirectories) { - options.ignore = dirGlob.sync(options.ignore); - } +/** + * Module dependencies + */ - return { - pattern: glob, - options - }; -}; +var toRegex = __webpack_require__(526); +var unique = __webpack_require__(548); +var extend = __webpack_require__(549); -const globby = (patterns, options) => { - let globTasks; +/** + * Local dependencies + */ - try { - globTasks = generateGlobTasks(patterns, options); - } catch (error) { - return Promise.reject(error); - } +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 = {}; - const getTasks = Promise.all(globTasks.map(task => Promise.resolve(getPattern(task, dirGlob)) - .then(globs => Promise.all(globs.map(globToTask(task)))) - )) - .then(tasks => arrayUnion(...tasks)); +/** + * Convert the given `braces` pattern into a regex-compatible string. By default, only one string is generated for every input string. Set `options.expand` to true to return an array of patterns (similar to Bash or minimatch. Before using `options.expand`, it's recommended that you read the [performance notes](#performance)). + * + * ```js + * var braces = require('braces'); + * console.log(braces('{a,b,c}')); + * //=> ['(a|b|c)'] + * + * console.log(braces('{a,b,c}', {expand: true})); + * //=> ['a', 'b', 'c'] + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {String} + * @api public + */ - const getFilter = () => { - return Promise.resolve( - options && options.gitignore ? - gitignore({cwd: options.cwd, ignore: options.ignore}) : - DEFAULT_FILTER - ); - }; +function braces(pattern, options) { + var key = utils.createKey(String(pattern), options); + var arr = []; - return getFilter() - .then(filter => { - return getTasks - .then(tasks => Promise.all(tasks.map(task => fastGlob(task.pattern, task.options)))) - .then(paths => arrayUnion(...paths)) - .then(paths => paths.filter(p => !filter(p))); - }); -}; + var disabled = options && options.cache === false; + if (!disabled && cache.hasOwnProperty(key)) { + return cache[key]; + } -module.exports = globby; -// TODO: Remove this for the next major release -module.exports.default = globby; + if (Array.isArray(pattern)) { + for (var i = 0; i < pattern.length; i++) { + arr.push.apply(arr, braces.create(pattern[i], options)); + } + } else { + arr = braces.create(pattern, options); + } -module.exports.sync = (patterns, options) => { - const globTasks = generateGlobTasks(patterns, options); + if (options && options.nodupes === true) { + arr = unique(arr); + } - const getFilter = () => { - return options && options.gitignore ? - gitignore.sync({cwd: options.cwd, ignore: options.ignore}) : - DEFAULT_FILTER; - }; + if (!disabled) { + cache[key] = arr; + } + return arr; +} - const tasks = globTasks.reduce((tasks, task) => { - const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); - return tasks.concat(newTask); - }, []); +/** + * 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 [.optimize](#optimize) instead. + * + * ```js + * var 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 + */ - const filter = getFilter(); - return tasks.reduce( - (matches, task) => arrayUnion(matches, fastGlob.sync(task.pattern, task.options)), - [] - ).filter(p => !filter(p)); +braces.expand = function(pattern, options) { + return braces.create(pattern, extend({}, options, {expand: true})); }; -module.exports.generateGlobTasks = generateGlobTasks; +/** + * Expands a brace pattern into a regex-compatible, optimized string. This method is called by the main [braces](#braces) function by default. + * + * ```js + * var braces = require('braces'); + * console.log(braces.expand('a/{b,c}/d')); + * //=> ['a/(b|c)/d'] + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ -module.exports.hasMagic = (patterns, options) => [] - .concat(patterns) - .some(pattern => glob.hasMagic(pattern, options)); +braces.optimize = function(pattern, options) { + return braces.create(pattern, options); +}; -module.exports.gitignore = gitignore; +/** + * 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 + * var 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 + */ +braces.create = function(pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('expected a string'); + } -/***/ }), -/* 503 */ -/***/ (function(module, exports, __webpack_require__) { + var maxLength = (options && options.maxLength) || MAX_LENGTH; + if (pattern.length >= maxLength) { + throw new Error('expected pattern to be less than ' + maxLength + ' characters'); + } -"use strict"; + function create() { + if (pattern === '' || pattern.length < 3) { + return [pattern]; + } -var arrayUniq = __webpack_require__(504); + if (utils.isEmptySets(pattern)) { + return []; + } -module.exports = function () { - return arrayUniq([].concat.apply([], arguments)); -}; + if (utils.isQuotedString(pattern)) { + return [pattern.slice(1, -1)]; + } + var proto = new Braces(options); + var result = !options || options.expand !== true + ? proto.optimize(pattern, options) + : proto.expand(pattern, options); -/***/ }), -/* 504 */ -/***/ (function(module, exports, __webpack_require__) { + // get the generated pattern(s) + var arr = result.output; -"use strict"; + // filter out empty strings if specified + if (options && options.noempty === true) { + arr = arr.filter(Boolean); + } + // filter out duplicates if specified + if (options && options.nodupes === true) { + arr = unique(arr); + } -// there's 3 implementations written in increasing order of efficiency + Object.defineProperty(arr, 'result', { + enumerable: false, + value: result + }); -// 1 - no Set type is defined -function uniqNoSet(arr) { - var ret = []; + return arr; + } - for (var i = 0; i < arr.length; i++) { - if (ret.indexOf(arr[i]) === -1) { - ret.push(arr[i]); - } - } + return memoize('create', pattern, options, create); +}; - return ret; -} +/** + * Create a regular expression from the given string `pattern`. + * + * ```js + * var braces = require('braces'); + * + * console.log(braces.makeRe('id-{200..300}')); + * //=> /^(?:id-(20[0-9]|2[1-9][0-9]|300))$/ + * ``` + * @param {String} `pattern` The pattern to convert to regex. + * @param {Object} `options` + * @return {RegExp} + * @api public + */ -// 2 - a simple Set type is defined -function uniqSet(arr) { - var seen = new Set(); - return arr.filter(function (el) { - if (!seen.has(el)) { - seen.add(el); - return true; - } +braces.makeRe = function(pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('expected a string'); + } - return false; - }); -} + var maxLength = (options && options.maxLength) || MAX_LENGTH; + if (pattern.length >= maxLength) { + throw new Error('expected pattern to be less than ' + maxLength + ' characters'); + } -// 3 - a standard Set type is defined and it has a forEach method -function uniqSetWithForEach(arr) { - var ret = []; + function makeRe() { + var arr = braces(pattern, options); + var opts = extend({strictErrors: false}, options); + return toRegex(arr, opts); + } - (new Set(arr)).forEach(function (el) { - ret.push(el); - }); + return memoize('makeRe', pattern, options, makeRe); +}; - return ret; -} +/** + * Parse the given `str` with the given `options`. + * + * ```js + * var braces = require('braces'); + * var ast = braces.parse('a/{b,c}/d'); + * console.log(ast); + * // { type: 'root', + * // errors: [], + * // input: 'a/{b,c}/d', + * // nodes: + * // [ { type: 'bos', val: '' }, + * // { type: 'text', val: 'a/' }, + * // { type: 'brace', + * // nodes: + * // [ { type: 'brace.open', val: '{' }, + * // { type: 'text', val: 'b,c' }, + * // { type: 'brace.close', val: '}' } ] }, + * // { type: 'text', val: '/d' }, + * // { type: 'eos', val: '' } ] } + * ``` + * @param {String} `pattern` Brace pattern to parse + * @param {Object} `options` + * @return {Object} Returns an AST + * @api public + */ -// V8 currently has a broken implementation -// https://github.com/joyent/node/issues/8449 -function doesForEachActuallyWork() { - var ret = false; +braces.parse = function(pattern, options) { + var proto = new Braces(options); + return proto.parse(pattern, options); +}; - (new Set([true])).forEach(function (el) { - ret = el; - }); +/** + * Compile the given `ast` or string with the given `options`. + * + * ```js + * var braces = require('braces'); + * var ast = braces.parse('a/{b,c}/d'); + * console.log(braces.compile(ast)); + * // { options: { source: 'string' }, + * // state: {}, + * // compilers: + * // { eos: [Function], + * // noop: [Function], + * // bos: [Function], + * // brace: [Function], + * // 'brace.open': [Function], + * // text: [Function], + * // 'brace.close': [Function] }, + * // output: [ 'a/(b|c)/d' ], + * // ast: + * // { ... }, + * // parsingErrors: [] } + * ``` + * @param {Object|String} `ast` AST from [.parse](#parse). If a string is passed it will be parsed first. + * @param {Object} `options` + * @return {Object} Returns an object that has an `output` property with the compiled string. + * @api public + */ - return ret === true; -} +braces.compile = function(ast, options) { + var proto = new Braces(options); + return proto.compile(ast, options); +}; -if ('Set' in global) { - if (typeof Set.prototype.forEach === 'function' && doesForEachActuallyWork()) { - module.exports = uniqSetWithForEach; - } else { - module.exports = uniqSet; - } -} else { - module.exports = uniqNoSet; -} +/** + * Clear the regex cache. + * + * ```js + * braces.clearCache(); + * ``` + * @api public + */ +braces.clearCache = function() { + cache = braces.cache = {}; +}; -/***/ }), -/* 505 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Memoize a generated regex or function. A unique key is generated + * from the method name, pattern, and user-defined options. Set + * options.memoize to false to disable. + */ -const pkg = __webpack_require__(506); +function memoize(type, pattern, options, fn) { + var key = utils.createKey(type + ':' + pattern, options); + var disabled = options && options.cache === false; + if (disabled) { + braces.clearCache(); + return fn(pattern, options); + } -module.exports = pkg.async; -module.exports.default = pkg.async; + if (cache.hasOwnProperty(key)) { + return cache[key]; + } -module.exports.async = pkg.async; -module.exports.sync = pkg.sync; -module.exports.stream = pkg.stream; + var res = fn(pattern, options); + cache[key] = res; + return res; +} -module.exports.generateTasks = pkg.generateTasks; +/** + * Expose `Braces` constructor and methods + * @type {Function} + */ +braces.Braces = Braces; +braces.compilers = compilers; +braces.parsers = parsers; +braces.cache = cache; -/***/ }), -/* 506 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * Expose `braces` + * @type {Function} + */ -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var optionsManager = __webpack_require__(507); -var taskManager = __webpack_require__(508); -var reader_async_1 = __webpack_require__(664); -var reader_stream_1 = __webpack_require__(688); -var reader_sync_1 = __webpack_require__(689); -var arrayUtils = __webpack_require__(691); -var streamUtils = __webpack_require__(692); -/** - * Synchronous API. - */ -function sync(source, opts) { - assertPatternsInput(source); - var works = getWorks(source, reader_sync_1.default, opts); - return arrayUtils.flatten(works); -} -exports.sync = sync; -/** - * Asynchronous API. - */ -function async(source, opts) { - try { - assertPatternsInput(source); - } - catch (error) { - return Promise.reject(error); - } - var works = getWorks(source, reader_async_1.default, opts); - return Promise.all(works).then(arrayUtils.flatten); -} -exports.async = async; -/** - * Stream API. - */ -function stream(source, opts) { - assertPatternsInput(source); - var works = getWorks(source, reader_stream_1.default, opts); - return streamUtils.merge(works); -} -exports.stream = stream; -/** - * Return a set of tasks based on provided patterns. - */ -function generateTasks(source, opts) { - assertPatternsInput(source); - var patterns = [].concat(source); - var options = optionsManager.prepare(opts); - return taskManager.generate(patterns, options); -} -exports.generateTasks = generateTasks; -/** - * Returns a set of works based on provided tasks and class of the reader. - */ -function getWorks(source, _Reader, opts) { - var patterns = [].concat(source); - var options = optionsManager.prepare(opts); - var tasks = taskManager.generate(patterns, options); - var reader = new _Reader(options); - return tasks.map(reader.read, reader); -} -function assertPatternsInput(source) { - if ([].concat(source).every(isString)) { - return; - } - throw new TypeError('Patterns must be a string or an array of strings'); -} -function isString(source) { - /* tslint:disable-next-line strict-type-predicates */ - return typeof source === 'string'; -} +module.exports = braces; /***/ }), -/* 507 */ +/* 526 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __assign = (this && this.__assign) || function () { - __assign = Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -function prepare(options) { - var opts = __assign({ cwd: process.cwd(), deep: true, ignore: [], dot: false, stats: false, onlyFiles: true, onlyDirectories: false, followSymlinkedDirectories: true, unique: true, markDirectories: false, absolute: false, nobrace: false, brace: true, noglobstar: false, globstar: true, noext: false, extension: true, nocase: false, case: true, matchBase: false, transform: null }, options); - if (opts.onlyDirectories) { - opts.onlyFiles = false; - } - opts.brace = !opts.nobrace; - opts.globstar = !opts.noglobstar; - opts.extension = !opts.noext; - opts.case = !opts.nocase; - if (options) { - opts.brace = ('brace' in options ? options.brace : opts.brace); - opts.globstar = ('globstar' in options ? options.globstar : opts.globstar); - opts.extension = ('extension' in options ? options.extension : opts.extension); - opts.case = ('case' in options ? options.case : opts.case); - } - return opts; -} -exports.prepare = prepare; -/***/ }), -/* 508 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var patternUtils = __webpack_require__(509); -/** - * Generate tasks based on parent directory of each pattern. - */ -function generate(patterns, options) { - var unixPatterns = patterns.map(patternUtils.unixifyPattern); - var unixIgnore = options.ignore.map(patternUtils.unixifyPattern); - var positivePatterns = getPositivePatterns(unixPatterns); - var negativePatterns = getNegativePatternsAsPositive(unixPatterns, unixIgnore); - /** - * When the `case` option is disabled, all patterns must be marked as dynamic, because we cannot check filepath - * directly (without read directory). - */ - var staticPatterns = !options.case ? [] : positivePatterns.filter(patternUtils.isStaticPattern); - var dynamicPatterns = !options.case ? positivePatterns : positivePatterns.filter(patternUtils.isDynamicPattern); - var staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false); - var dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true); - return staticTasks.concat(dynamicTasks); -} -exports.generate = generate; -/** - * Convert patterns to tasks based on parent directory of each pattern. - */ -function convertPatternsToTasks(positive, negative, dynamic) { - var 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) { - var task = convertPatternGroupToTask('.', positive, negative, dynamic); - return [task]; - } - return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic); -} -exports.convertPatternsToTasks = convertPatternsToTasks; -/** - * Return only positive patterns. - */ -function getPositivePatterns(patterns) { - return patternUtils.getPositivePatterns(patterns); -} -exports.getPositivePatterns = getPositivePatterns; -/** - * Return only negative patterns. - */ -function getNegativePatternsAsPositive(patterns, ignore) { - var negative = patternUtils.getNegativePatterns(patterns).concat(ignore); - var positive = negative.map(patternUtils.convertToPositivePattern); - return positive; -} -exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; -/** - * Group patterns by base directory of each pattern. - */ -function groupPatternsByBaseDirectory(patterns) { - return patterns.reduce(function (collection, pattern) { - var base = patternUtils.getBaseDirectory(pattern); - if (base in collection) { - collection[base].push(pattern); - } - else { - collection[base] = [pattern]; - } - return collection; - }, {}); -} -exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; -/** - * Convert group of patterns to tasks. - */ -function convertPatternGroupsToTasks(positive, negative, dynamic) { - return Object.keys(positive).map(function (base) { - return convertPatternGroupToTask(base, positive[base], negative, dynamic); - }); -} -exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; -/** - * Create a task for positive and negative patterns. - */ -function convertPatternGroupToTask(base, positive, negative, dynamic) { - return { - base: base, - dynamic: dynamic, - positive: positive, - negative: negative, - patterns: [].concat(positive, negative.map(patternUtils.convertToNegativePattern)) - }; -} -exports.convertPatternGroupToTask = convertPatternGroupToTask; +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; +/** + * Session cache + */ -/***/ }), -/* 509 */ -/***/ (function(module, exports, __webpack_require__) { +var cache = {}; -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var path = __webpack_require__(4); -var globParent = __webpack_require__(510); -var isGlob = __webpack_require__(513); -var micromatch = __webpack_require__(514); -var GLOBSTAR = '**'; -/** - * Return true for static pattern. - */ -function isStaticPattern(pattern) { - return !isDynamicPattern(pattern); -} -exports.isStaticPattern = isStaticPattern; -/** - * Return true for pattern that looks like glob. - */ -function isDynamicPattern(pattern) { - return isGlob(pattern, { strict: false }); -} -exports.isDynamicPattern = isDynamicPattern; -/** - * Convert a windows «path» to a unix-style «path». - */ -function unixifyPattern(pattern) { - return pattern.replace(/\\/g, '/'); -} -exports.unixifyPattern = unixifyPattern; -/** - * Returns negative pattern as positive pattern. - */ -function convertToPositivePattern(pattern) { - return isNegativePattern(pattern) ? pattern.slice(1) : pattern; -} -exports.convertToPositivePattern = convertToPositivePattern; -/** - * Returns positive pattern as negative pattern. - */ -function convertToNegativePattern(pattern) { - return '!' + pattern; -} -exports.convertToNegativePattern = convertToNegativePattern; -/** - * Return true if provided pattern is negative pattern. - */ -function isNegativePattern(pattern) { - return pattern.startsWith('!') && pattern[1] !== '('; -} -exports.isNegativePattern = isNegativePattern; -/** - * Return true if provided pattern is positive pattern. - */ -function isPositivePattern(pattern) { - return !isNegativePattern(pattern); -} -exports.isPositivePattern = isPositivePattern; -/** - * Extracts negative patterns from array of patterns. - */ -function getNegativePatterns(patterns) { - return patterns.filter(isNegativePattern); -} -exports.getNegativePatterns = getNegativePatterns; -/** - * Extracts positive patterns from array of patterns. - */ -function getPositivePatterns(patterns) { - return patterns.filter(isPositivePattern); -} -exports.getPositivePatterns = getPositivePatterns; -/** - * Extract base directory from provided pattern. - */ -function getBaseDirectory(pattern) { - return globParent(pattern); -} -exports.getBaseDirectory = getBaseDirectory; -/** - * Return true if provided pattern has globstar. - */ -function hasGlobStar(pattern) { - return pattern.indexOf(GLOBSTAR) !== -1; -} -exports.hasGlobStar = hasGlobStar; -/** - * Return true if provided pattern ends with slash and globstar. - */ -function endsWithSlashGlobStar(pattern) { - return pattern.endsWith('/' + GLOBSTAR); -} -exports.endsWithSlashGlobStar = endsWithSlashGlobStar; -/** - * Returns «true» when pattern ends with a slash and globstar or the last partial of the pattern is static pattern. - */ -function isAffectDepthOfReadingPattern(pattern) { - var basename = path.basename(pattern); - return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); -} -exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; -/** - * Return naive depth of provided pattern without depth of the base directory. - */ -function getNaiveDepth(pattern) { - var base = getBaseDirectory(pattern); - var patternDepth = pattern.split('/').length; - var patternBaseDepth = base.split('/').length; - /** - * This is a hack for pattern that has no base directory. - * - * This is related to the `*\something\*` pattern. - */ - if (base === '.') { - return patternDepth - patternBaseDepth; - } - return patternDepth - patternBaseDepth - 1; -} -exports.getNaiveDepth = getNaiveDepth; -/** - * Return max naive depth of provided patterns without depth of the base directory. - */ -function getMaxNaivePatternsDepth(patterns) { - return patterns.reduce(function (max, pattern) { - var depth = getNaiveDepth(pattern); - return depth > max ? depth : max; - }, 0); -} -exports.getMaxNaivePatternsDepth = getMaxNaivePatternsDepth; -/** - * Make RegExp for provided pattern. - */ -function makeRe(pattern, options) { - return micromatch.makeRe(pattern, options); -} -exports.makeRe = makeRe; -/** - * Convert patterns to regexps. - */ -function convertPatternsToRe(patterns, options) { - return patterns.map(function (pattern) { return makeRe(pattern, options); }); -} -exports.convertPatternsToRe = convertPatternsToRe; -/** - * Returns true if the entry match any of the given RegExp's. - */ -function matchAny(entry, patternsRe) { - return patternsRe.some(function (patternRe) { return patternRe.test(entry); }); -} -exports.matchAny = matchAny; +/** + * 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); +}; -/***/ }), -/* 510 */ -/***/ (function(module, exports, __webpack_require__) { +/** + * 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 + */ -"use strict"; +function makeRe(pattern, options) { + if (pattern instanceof RegExp) { + return pattern; + } + if (typeof pattern !== 'string') { + throw new TypeError('expected a string'); + } -var path = __webpack_require__(4); -var isglob = __webpack_require__(511); -var pathDirname = __webpack_require__(512); -var isWin32 = __webpack_require__(120).platform() === 'win32'; + if (pattern.length > MAX_LENGTH) { + throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); + } -module.exports = function globParent(str) { - // flip windows path separators - if (isWin32 && str.indexOf('/') < 0) str = str.split('\\').join('/'); + var key = pattern; + // do this before shallow cloning options, it's a lot faster + if (!options || (options && options.cache !== false)) { + key = createKey(pattern, options); - // special case for strings ending in enclosure containing path separator - if (/[\{\[].*[\/]*.*[\}\]]$/.test(str)) str += '/'; + if (cache.hasOwnProperty(key)) { + return cache[key]; + } + } - // preserves full path in case of trailing path separator - str += 'a'; + var opts = extend({}, options); + if (opts.contains === true) { + if (opts.negate === true) { + opts.strictNegate = false; + } else { + opts.strict = false; + } + } - // remove path parts that are globby - do {str = pathDirname.posix(str)} - while (isglob(str) || /(^|[^\\])([\{\[]|\([^\)]+$)/.test(str)); + if (opts.strict === false) { + opts.strictOpen = false; + opts.strictClose = false; + } - // remove escape chars and return result - return str.replace(/\\([\*\?\|\[\]\(\)\{\}])/g, '$1'); -}; + 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'; + } -/***/ }), -/* 511 */ -/***/ (function(module, exports, __webpack_require__) { + try { + if (opts.negate || typeof opts.strictNegate === 'boolean') { + pattern = not.create(pattern, opts); + } -/*! - * is-glob - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. - */ + var str = open + '(?:' + pattern + ')' + close; + regex = new RegExp(str, flags); -var isExtglob = __webpack_require__(299); + if (opts.safe === true && safe(regex) === false) { + throw new Error('potentially unsafe regular expression: ' + regex.source); + } -module.exports = function isGlob(str) { - if (typeof str !== 'string' || str === '') { - return false; + } catch (err) { + if (opts.strictErrors === true || opts.safe === 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 (isExtglob(str)) return true; + if (opts.cache !== false) { + memoize(regex, key, pattern, opts); + } + return regex; +} - var regex = /(\\).|([*?]|\[.*\]|\{.*\}|\(.*\|.*\)|^!)/; - var match; +/** + * 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. + */ - while ((match = regex.exec(str))) { - if (match[2]) return true; - str = str.slice(match.index + match[0].length); +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; +} + +/** + * 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 false; + return key; +} + +/** + * Expose `makeRe` + */ + +module.exports.makeRe = makeRe; + + +/***/ }), +/* 527 */ +/***/ (function(module, exports, __webpack_require__) { + +var parse = __webpack_require__(528); +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]'; +} + /***/ }), -/* 512 */ +/* 528 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var util = __webpack_require__(529); +var types = __webpack_require__(530); +var sets = __webpack_require__(531); +var positions = __webpack_require__(532); -var path = __webpack_require__(4); -var inspect = __webpack_require__(111).inspect; +module.exports = function(regexpStr) { + var i = 0, l, c, + start = { type: types.ROOT, stack: []}, -function assertPath(path) { - if (typeof path !== 'string') { - throw new TypeError('Path must be a string. Received ' + inspect(path)); - } -} + // Keep track of last clause/group and stack. + lastGroup = start, + last = start.stack, + groupStack = []; -function posix(path) { - assertPath(path); - if (path.length === 0) - return '.'; - var code = path.charCodeAt(0); - var hasRoot = (code === 47/*/*/); - var end = -1; - var matchedSlash = true; - for (var i = path.length - 1; i >= 1; --i) { - code = path.charCodeAt(i); - if (code === 47/*/*/) { - if (!matchedSlash) { - end = i; - break; - } - } else { - // We saw the first non-path separator - matchedSlash = false; - } - } - if (end === -1) - return hasRoot ? '/' : '.'; - if (hasRoot && end === 1) - return '//'; - return path.slice(0, end); -} + var repeatErr = function(i) { + util.error(regexpStr, 'Nothing to repeat at column ' + (i - 1)); + }; -function win32(path) { - assertPath(path); - var len = path.length; - if (len === 0) - return '.'; - var rootEnd = -1; - var end = -1; - var matchedSlash = true; - var offset = 0; - var code = path.charCodeAt(0); + // Decode a few escaped characters. + var str = util.strToChars(regexpStr); + l = str.length; - // Try to match a root - if (len > 1) { - if (code === 47/*/*/ || code === 92/*\*/) { - // Possible UNC root + // Iterate through each character in string. + while (i < l) { + c = str[i++]; - rootEnd = offset = 1; + switch (c) { + // Handle escaped characters, inclues a few sets. + case '\\': + c = str[i++]; - code = path.charCodeAt(1); - if (code === 47/*/*/ || code === 92/*\*/) { - // Matched double path separator at beginning - var j = 2; - var last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code === 47/*/*/ || code === 92/*\*/) + switch (c) { + case 'b': + last.push(positions.wordBoundary()); break; - } - if (j < len && j !== last) { - // Matched! - last = j; - // Match 1 or more path separators - for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code !== 47/*/*/ && code !== 92/*\*/) - break; - } - if (j < len && j !== last) { - // Matched! - last = j; - // Match 1 or more non-path separators - for (; j < len; ++j) { - code = path.charCodeAt(j); - if (code === 47/*/*/ || code === 92/*\*/) - break; - } - if (j === len) { - // We matched a UNC root only - return path; - } - if (j !== last) { - // We matched a UNC root with leftovers - // Offset by 1 to include the separator after the UNC root to - // treat it as a "normal root" on top of a (UNC) root - rootEnd = offset = j + 1; + case 'B': + last.push(positions.nonWordBoundary()); + break; + + case 'w': + last.push(sets.words()); + break; + + case 'W': + last.push(sets.notWords()); + break; + + case 'd': + last.push(sets.ints()); + break; + + case 'D': + last.push(sets.notInts()); + break; + + case 's': + last.push(sets.whitespace()); + break; + + case 'S': + last.push(sets.notWhitespace()); + break; + + 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) }); + + // Escaped character. + } else { + last.push({ type: types.CHAR, value: c.charCodeAt(0) }); } + } + + break; + + + // Positionals. + case '^': + last.push(positions.begin()); + break; + + case '$': + last.push(positions.end()); + break; + + + // 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); + + // Increase index by length of class. + i += classTokens[1]; + last.push({ + type: types.SET, + set: classTokens[0], + not: not, + }); + + break; + + + // Class of any character except \n. + case '.': + last.push(sets.anyChar()); + break; + + + // Push group onto stack. + case '(': + // Create group. + var group = { + type: types.GROUP, + stack: [], + remember: true, + }; + + c = str[i]; + + // If if this is a special kind of group. + if (c === '?') { + c = str[i + 1]; + i += 2; + + // Match if followed by. + if (c === '=') { + group.followedBy = true; + + // Match if not followed by. + } else if (c === '!') { + group.notFollowedBy = true; + + } else if (c !== ':') { + util.error(regexpStr, + 'Invalid group, character \'' + c + + '\' after \'?\' at column ' + (i - 1)); } + + group.remember = false; } - } - } else if ((code >= 65/*A*/ && code <= 90/*Z*/) || - (code >= 97/*a*/ && code <= 122/*z*/)) { - // Possible device root - code = path.charCodeAt(1); - if (path.charCodeAt(1) === 58/*:*/) { - rootEnd = offset = 2; - if (len > 2) { - code = path.charCodeAt(2); - if (code === 47/*/*/ || code === 92/*\*/) - rootEnd = offset = 3; + // Insert subgroup into current group stack. + last.push(group); + + // Remember the current group for when the group closes. + groupStack.push(lastGroup); + + // Make this new group the current group. + lastGroup = group; + last = group.stack; + break; + + + // Pop group out of stack. + case ')': + if (groupStack.length === 0) { + util.error(regexpStr, 'Unmatched ) at column ' + (i - 1)); } - } - } - } else if (code === 47/*/*/ || code === 92/*\*/) { - return path[0]; - } + lastGroup = groupStack.pop(); - for (var i = len - 1; i >= offset; --i) { - code = path.charCodeAt(i); - if (code === 47/*/*/ || code === 92/*\*/) { - if (!matchedSlash) { - end = i; + // 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; - } - } else { - // We saw the first non-path separator - matchedSlash = false; - } - } - if (end === -1) { - if (rootEnd === -1) - return '.'; - else - end = rootEnd; - } - return path.slice(0, end); -} -module.exports = process.platform === 'win32' ? win32 : posix; -module.exports.posix = posix; -module.exports.win32 = win32; + // 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; + } + + // Create a new stack and add to options for rest of clause. + var stack = []; + lastGroup.options.push(stack); + last = stack; + break; + + + // 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; + + last.push({ + type: types.REPETITION, + min: min, + max: max, + value: last.pop(), + }); + } else { + last.push({ + type: types.CHAR, + value: 123, + }); + } + break; + case '?': + if (last.length === 0) { + repeatErr(i); + } + last.push({ + type: types.REPETITION, + min: 0, + max: 1, + value: last.pop(), + }); + break; -/***/ }), -/* 513 */ -/***/ (function(module, exports, __webpack_require__) { + case '+': + if (last.length === 0) { + repeatErr(i); + } + last.push({ + type: types.REPETITION, + min: 1, + max: Infinity, + value: last.pop(), + }); + break; -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ + case '*': + if (last.length === 0) { + repeatErr(i); + } + last.push({ + type: types.REPETITION, + min: 0, + max: Infinity, + value: last.pop(), + }); + break; -var isExtglob = __webpack_require__(299); -var chars = { '{': '}', '(': ')', '[': ']'}; -module.exports = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; - } + // Default is a character that is not `\[](){}?+*^$`. + default: + last.push({ + type: types.CHAR, + value: c.charCodeAt(0), + }); + } - if (isExtglob(str)) { - return true; } - var regex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; - var match; - - // optionally relax regex - if (options && options.strict === false) { - regex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; + // Check if any groups have not been closed. + if (groupStack.length !== 0) { + util.error(regexpStr, 'Unterminated group'); } - 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; + return start; }; +module.exports.types = types; + /***/ }), -/* 514 */ +/* 529 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -/** - * Module dependencies - */ +var types = __webpack_require__(530); +var sets = __webpack_require__(531); -var util = __webpack_require__(111); -var braces = __webpack_require__(515); -var toRegex = __webpack_require__(617); -var extend = __webpack_require__(625); -/** - * Local dependencies - */ +// All of these are private and only used by randexp. +// It's assumed that they will always be called with the correct input. -var compilers = __webpack_require__(628); -var parsers = __webpack_require__(660); -var cache = __webpack_require__(661); -var utils = __webpack_require__(662); -var MAX_LENGTH = 1024 * 64; +var CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?'; +var SLSH = { '0': 0, 't': 9, 'n': 10, 'v': 11, 'f': 12, 'r': 13 }; /** - * The main function takes a list of strings and one or more - * glob patterns to use for matching. - * - * ```js - * var mm = require('micromatch'); - * mm(list, patterns[, options]); + * Finds character representations in str and convert all to + * their respective characters * - * console.log(mm(['a.js', 'a.txt'], ['*.js'])); - * //=> [ 'a.js' ] - * ``` - * @param {Array} `list` A 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) for changing how matches are performed - * @return {Array} Returns an array of matches - * @summary false - * @api public + * @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; + } -function micromatch(list, patterns, options) { - patterns = utils.arrayify(patterns); - list = utils.arrayify(list); - - var len = patterns.length; - if (list.length === 0 || len === 0) { - return []; - } - - if (len === 1) { - return micromatch.match(list, patterns[0], options); - } - - var omit = []; - var keep = []; - var idx = -1; + var code = b ? 8 : + a16 ? parseInt(a16, 16) : + b16 ? parseInt(b16, 16) : + c8 ? parseInt(c8, 8) : + dctrl ? CTRL.indexOf(dctrl) : + SLSH[eslsh]; - while (++idx < len) { - var pattern = patterns[idx]; + var c = String.fromCharCode(code); - if (typeof pattern === 'string' && pattern.charCodeAt(0) === 33 /* ! */) { - omit.push.apply(omit, micromatch.match(list, pattern.slice(1), options)); - } else { - keep.push.apply(keep, micromatch.match(list, pattern, options)); + // Escape special regex characters. + if (/[\[\]{}\^$.|?*+()]/.test(c)) { + c = '\\' + c; } - } - var matches = utils.diff(keep, omit); - if (!options || options.nodupes !== false) { - return utils.unique(matches); - } + return c; + }); + + return str; +}; - return matches; -} /** - * Similar to the main function, but `pattern` must be a string. - * - * ```js - * var mm = require('micromatch'); - * mm.match(list, pattern[, options]); + * turns class into tokens + * reads str until it encounters a ] not preceeded by a \ * - * console.log(mm.match(['a.a', 'a.aa', 'a.b', 'a.c'], '*.a')); - * //=> ['a.a', 'a.aa'] - * ``` - * @param {Array} `list` Array of strings to match - * @param {String} `pattern` 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 matches - * @api public + * @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; -micromatch.match = function(list, pattern, options) { - if (Array.isArray(pattern)) { - throw new TypeError('expected pattern to be a string'); - } - var unixify = utils.unixify(options); - var isMatch = memoize('match', pattern, options, micromatch.matcher); - var matches = []; + while ((rs = regexp.exec(str)) != null) { + if (rs[1]) { + tokens.push(sets.words()); - list = utils.arrayify(list); - var len = list.length; - var idx = -1; + } else if (rs[2]) { + tokens.push(sets.ints()); - while (++idx < len) { - var ele = list[idx]; - if (ele === pattern || isMatch(ele)) { - matches.push(utils.value(ele, unixify, options)); - } - } + } else if (rs[3]) { + tokens.push(sets.whitespace()); - // if no options were passed, uniquify results and return - if (typeof options === 'undefined') { - return utils.unique(matches); - } + } else if (rs[4]) { + tokens.push(sets.notWords()); - if (matches.length === 0) { - if (options.failglob === true) { - throw new Error('no matches found for "' + pattern + '"'); - } - if (options.nonull === true || options.nullglob === true) { - return [options.unescape ? utils.unescape(pattern) : pattern]; - } - } + } else if (rs[5]) { + tokens.push(sets.notInts()); - // if `opts.ignore` was defined, diff ignored list - if (options.ignore) { - matches = micromatch.not(matches, options.ignore, options); + } else if (rs[6]) { + tokens.push(sets.notWhitespace()); + + } else if (rs[7]) { + tokens.push({ + type: types.RANGE, + from: (rs[8] || rs[9]).charCodeAt(0), + to: rs[10].charCodeAt(0), + }); + + } else if (c = rs[12]) { + tokens.push({ + type: types.CHAR, + value: c.charCodeAt(0), + }); + + } else { + return [tokens, regexp.lastIndex]; + } } - return options.nodupes !== false ? utils.unique(matches) : matches; + exports.error(regexpStr, 'Unterminated character class'); }; + /** - * Returns true if the specified `string` matches the given glob `pattern`. - * - * ```js - * var mm = require('micromatch'); - * mm.isMatch(string, pattern[, options]); + * Shortcut to throw errors. * - * console.log(mm.isMatch('a.a', '*.a')); - * //=> true - * console.log(mm.isMatch('a.b', '*.a')); - * //=> false - * ``` - * @param {String} `string` String to match - * @param {String} `pattern` 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 string matches the glob pattern. - * @api public + * @param {String} regexp + * @param {String} msg */ +exports.error = function(regexp, msg) { + throw new SyntaxError('Invalid regular expression: /' + regexp + '/: ' + msg); +}; -micromatch.isMatch = function(str, pattern, options) { - if (typeof str !== 'string') { - throw new TypeError('expected a string: "' + util.inspect(str) + '"'); - } - - if (isEmptyString(str) || isEmptyString(pattern)) { - return false; - } - var equals = utils.equalsPattern(options); - if (equals(str)) { - return true; - } +/***/ }), +/* 530 */ +/***/ (function(module, exports) { - var isMatch = memoize('isMatch', pattern, options, micromatch.matcher); - return isMatch(str); +module.exports = { + ROOT : 0, + GROUP : 1, + POSITION : 2, + SET : 3, + RANGE : 4, + REPETITION : 5, + REFERENCE : 6, + CHAR : 7, }; -/** - * Returns true if some of the strings in the given `list` match any of the - * given glob `patterns`. - * - * ```js - * var 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 - */ -micromatch.some = function(list, patterns, options) { - if (typeof list === 'string') { - list = [list]; - } - for (var i = 0; i < list.length; i++) { - if (micromatch(list[i], patterns, options).length === 1) { - return true; - } - } - return false; -}; +/***/ }), +/* 531 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Returns true if every string in the given `list` matches - * any of the given glob `patterns`. - * - * ```js - * var 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 - */ +var types = __webpack_require__(530); -micromatch.every = function(list, patterns, options) { - if (typeof list === 'string') { - list = [list]; - } - for (var i = 0; i < list.length; i++) { - if (micromatch(list[i], patterns, options).length !== 1) { - return false; - } - } - return true; +var INTS = function() { + return [{ type: types.RANGE , from: 48, to: 57 }]; }; -/** - * Returns true if **any** of the given glob `patterns` - * match the specified `string`. - * - * ```js - * var mm = require('micromatch'); - * mm.any(string, patterns[, options]); - * - * console.log(mm.any('a.a', ['b.*', '*.a'])); - * //=> true - * console.log(mm.any('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) for changing how matches are performed - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ - -micromatch.any = function(str, patterns, options) { - if (typeof str !== 'string') { - throw new TypeError('expected a string: "' + util.inspect(str) + '"'); - } +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()); +}; - if (isEmptyString(str) || isEmptyString(patterns)) { - return false; - } +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 } + ]; +}; - if (typeof patterns === 'string') { - patterns = [patterns]; - } +var NOTANYCHAR = function() { + return [ + { type: types.CHAR, value: 10 }, + { type: types.CHAR, value: 13 }, + { type: types.CHAR, value: 8232 }, + { type: types.CHAR, value: 8233 }, + ]; +}; - for (var i = 0; i < patterns.length; i++) { - if (micromatch.isMatch(str, patterns[i], options)) { - return true; - } - } - return false; +// Predefined class objects. +exports.words = function() { + return { type: types.SET, set: WORDS(), not: false }; }; -/** - * Returns true if **all** of the given `patterns` match - * the specified string. - * - * ```js - * var 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 - */ +exports.notWords = function() { + return { type: types.SET, set: WORDS(), not: true }; +}; -micromatch.all = function(str, patterns, options) { - if (typeof str !== 'string') { - throw new TypeError('expected a string: "' + util.inspect(str) + '"'); - } - if (typeof patterns === 'string') { - patterns = [patterns]; - } - for (var i = 0; i < patterns.length; i++) { - if (!micromatch.isMatch(str, patterns[i], options)) { - return false; - } - } - return true; +exports.ints = function() { + return { type: types.SET, set: INTS(), not: false }; }; -/** - * Returns a list of strings that _**do not match any**_ of the given `patterns`. - * - * ```js - * var 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 - */ - -micromatch.not = function(list, patterns, options) { - var opts = extend({}, options); - var ignore = opts.ignore; - delete opts.ignore; +exports.notInts = function() { + return { type: types.SET, set: INTS(), not: true }; +}; - var unixify = utils.unixify(opts); - list = utils.arrayify(list).map(unixify); +exports.whitespace = function() { + return { type: types.SET, set: WHITESPACE(), not: false }; +}; - var matches = utils.diff(list, micromatch(list, patterns, opts)); - if (ignore) { - matches = utils.diff(matches, micromatch(list, ignore)); - } +exports.notWhitespace = function() { + return { type: types.SET, set: WHITESPACE(), not: true }; +}; - return opts.nodupes !== false ? utils.unique(matches) : matches; +exports.anyChar = function() { + return { type: types.SET, set: NOTANYCHAR(), not: true }; }; -/** - * 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 - */ -micromatch.contains = function(str, patterns, options) { - if (typeof str !== 'string') { - throw new TypeError('expected a string: "' + util.inspect(str) + '"'); - } +/***/ }), +/* 532 */ +/***/ (function(module, exports, __webpack_require__) { - if (typeof patterns === 'string') { - if (isEmptyString(str) || isEmptyString(patterns)) { - return false; - } +var types = __webpack_require__(530); - var equals = utils.equalsPattern(patterns, options); - if (equals(str)) { - return true; - } - var contains = utils.containsPattern(patterns, options); - if (contains(str)) { - return true; - } - } +exports.wordBoundary = function() { + return { type: types.POSITION, value: 'b' }; +}; - var opts = extend({}, options, {contains: true}); - return micromatch.any(str, patterns, opts); +exports.nonWordBoundary = function() { + return { type: types.POSITION, value: 'B' }; }; -/** - * Returns true if the given pattern and options should enable - * the `matchBase` option. - * @return {Boolean} - * @api private - */ +exports.begin = function() { + return { type: types.POSITION, value: '^' }; +}; -micromatch.matchBase = function(pattern, options) { - if (pattern && pattern.indexOf('/') !== -1 || !options) return false; - return options.basename === true || options.matchBase === true; +exports.end = function() { + return { type: types.POSITION, value: '$' }; }; -/** - * 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 - * var mm = require('micromatch'); - * mm.matchKeys(object, patterns[, options]); - * - * var 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 - */ -micromatch.matchKeys = function(obj, patterns, options) { - if (!utils.isObject(obj)) { - throw new TypeError('expected the first argument to be an object'); - } - var keys = micromatch(Object.keys(obj), patterns, options); - return utils.pick(obj, keys); -}; +/***/ }), +/* 533 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Returns a memoized 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 - * var mm = require('micromatch'); - * mm.matcher(pattern[, options]); +"use strict"; +/*! + * define-property * - * var isMatch = mm.matcher('*.!(*a)'); - * console.log(isMatch('a.a')); - * //=> false - * console.log(isMatch('a.b')); - * //=> true - * ``` - * @param {String} `pattern` Glob pattern - * @param {Object} `options` See available [options](#options) for changing how matches are performed. - * @return {Function} Returns a matcher function. - * @api public + * Copyright (c) 2015-2018, Jon Schlinkert. + * Released under the MIT License. */ -micromatch.matcher = function matcher(pattern, options) { - if (Array.isArray(pattern)) { - return compose(pattern, options, matcher); - } - // if pattern is a regex - if (pattern instanceof RegExp) { - return test(pattern); - } - // if pattern is invalid - if (!utils.isString(pattern)) { - throw new TypeError('expected pattern to be an array, string or regex'); - } +var isobject = __webpack_require__(534); +var isDescriptor = __webpack_require__(535); +var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) + ? Reflect.defineProperty + : Object.defineProperty; - // if pattern is a non-glob string - if (!utils.hasSpecialChars(pattern)) { - if (options && options.nocase === true) { - pattern = pattern.toLowerCase(); - } - return utils.matchPath(pattern, options); +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 pattern is a glob string - var re = micromatch.makeRe(pattern, options); - - // if `options.matchBase` or `options.basename` is defined - if (micromatch.matchBase(pattern, options)) { - return utils.matchBasename(re, options); + if (typeof key !== 'string') { + throw new TypeError('expected "key" to be a string'); } - function test(regex) { - var equals = utils.equalsPattern(options); - var unixify = utils.unixify(options); - - return function(str) { - if (equals(str)) { - return true; - } - - if (regex.test(unixify(str))) { - return true; - } - return false; - }; + if (isDescriptor(val)) { + define(obj, key, val); + return obj; } - var fn = test(re); - Object.defineProperty(fn, 'result', { + define(obj, key, { configurable: true, enumerable: false, - value: re.result + writable: true, + value: val }); - return fn; -}; - -/** - * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. - * - * ```js - * var 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} `pattern` Glob pattern to use for matching. - * @param {String} `string` 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 string matches the glob pattern, otherwise `null`. - * @api public - */ - -micromatch.capture = function(pattern, str, options) { - var re = micromatch.makeRe(pattern, extend({capture: true}, options)); - var unixify = utils.unixify(options); - function match() { - return function(string) { - var match = re.exec(unixify(string)); - if (!match) { - return null; - } + return obj; +}; - return match.slice(1); - }; - } - var capture = memoize('capture', pattern, options, match); - return capture(str); -}; +/***/ }), +/* 534 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Create a regular expression from the given glob `pattern`. - * - * ```js - * var mm = require('micromatch'); - * mm.makeRe(pattern[, options]); +"use strict"; +/*! + * isobject * - * console.log(mm.makeRe('*.js')); - * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ - * ``` - * @param {String} `pattern` A glob pattern to convert to regex. - * @param {Object} `options` See available [options](#options) for changing how matches are performed. - * @return {RegExp} Returns a regex created from the given pattern. - * @api public + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. */ -micromatch.makeRe = function(pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('expected pattern to be a string'); - } - if (pattern.length > MAX_LENGTH) { - throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); - } - function makeRe() { - var result = micromatch.create(pattern, options); - var ast_array = []; - var output = result.map(function(obj) { - obj.ast.state = obj.state; - ast_array.push(obj.ast); - return obj.output; - }); +module.exports = function isObject(val) { + return val != null && typeof val === 'object' && Array.isArray(val) === false; +}; - var regex = toRegex(output.join('|'), options); - Object.defineProperty(regex, 'result', { - configurable: true, - enumerable: false, - value: ast_array - }); - return regex; - } - return memoize('makeRe', pattern, options, makeRe); -}; +/***/ }), +/* 535 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Expand the given brace `pattern`. - * - * ```js - * var mm = require('micromatch'); - * console.log(mm.braces('foo/{a,b}/bar')); - * //=> ['foo/(a|b)/bar'] +"use strict"; +/*! + * is-descriptor * - * console.log(mm.braces('foo/{a,b}/bar', {expand: true})); - * //=> ['foo/(a|b)/bar'] - * ``` - * @param {String} `pattern` String with brace pattern to expand. - * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. - * @return {Array} - * @api public + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -micromatch.braces = function(pattern, options) { - if (typeof pattern !== 'string' && !Array.isArray(pattern)) { - throw new TypeError('expected pattern to be an array or string'); - } - - function expand() { - if (options && options.nobrace === true || !/\{.*\}/.test(pattern)) { - return utils.arrayify(pattern); - } - return braces(pattern, options); - } - return memoize('braces', pattern, options, expand); -}; -/** - * Proxy to the [micromatch.braces](#method), for parity with - * minimatch. - */ +var typeOf = __webpack_require__(536); +var isAccessor = __webpack_require__(537); +var isData = __webpack_require__(539); -micromatch.braceExpand = function(pattern, options) { - var opts = extend({}, options, {expand: true}); - return micromatch.braces(pattern, opts); +module.exports = function isDescriptor(obj, key) { + if (typeOf(obj) !== 'object') { + return false; + } + if ('get' in obj) { + return isAccessor(obj, key); + } + return isData(obj, key); }; -/** - * Parses the given glob `pattern` and returns an array of abstract syntax - * trees (ASTs), with the compiled `output` and optional source `map` on - * each AST. - * - * ```js - * var mm = require('micromatch'); - * mm.create(pattern[, options]); - * - * console.log(mm.create('abc/*.js')); - * // [{ options: { source: 'string', sourcemap: true }, - * // state: {}, - * // compilers: - * // { ... }, - * // output: '(\\.[\\\\\\/])?abc\\/(?!\\.)(?=.)[^\\/]*?\\.js', - * // ast: - * // { type: 'root', - * // errors: [], - * // nodes: - * // [ ... ], - * // dot: false, - * // input: 'abc/*.js' }, - * // parsingErrors: [], - * // map: - * // { version: 3, - * // sources: [ 'string' ], - * // names: [], - * // mappings: 'AAAA,GAAG,EAAC,kBAAC,EAAC,EAAE', - * // sourcesContent: [ 'abc/*.js' ] }, - * // position: { line: 1, column: 28 }, - * // content: {}, - * // files: {}, - * // idx: 6 }] - * ``` - * @param {String} `pattern` Glob pattern to parse and compile. - * @param {Object} `options` Any [options](#options) to change how parsing and compiling is performed. - * @return {Object} Returns an object with the parsed AST, compiled string and optional source map. - * @api public - */ - -micromatch.create = function(pattern, options) { - return memoize('create', pattern, options, function() { - function create(str, opts) { - return micromatch.compile(micromatch.parse(str, opts), opts); - } - pattern = micromatch.braces(pattern, options); - var len = pattern.length; - var idx = -1; - var res = []; +/***/ }), +/* 536 */ +/***/ (function(module, exports) { - while (++idx < len) { - res.push(create(pattern[idx], options)); - } - return res; - }); -}; +var toString = Object.prototype.toString; -/** - * Parse the given `str` with the given `options`. - * - * ```js - * var mm = require('micromatch'); - * mm.parse(pattern[, options]); - * - * var ast = mm.parse('a/{b,c}/d'); - * console.log(ast); - * // { type: 'root', - * // errors: [], - * // input: 'a/{b,c}/d', - * // nodes: - * // [ { type: 'bos', val: '' }, - * // { type: 'text', val: 'a/' }, - * // { type: 'brace', - * // nodes: - * // [ { type: 'brace.open', val: '{' }, - * // { type: 'text', val: 'b,c' }, - * // { type: 'brace.close', val: '}' } ] }, - * // { type: 'text', val: '/d' }, - * // { type: 'eos', val: '' } ] } - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {Object} Returns an AST - * @api public - */ +module.exports = function kindOf(val) { + if (val === void 0) return 'undefined'; + if (val === null) return 'null'; -micromatch.parse = function(pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('expected a string'); + 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'; } - function parse() { - var snapdragon = utils.instantiate(null, options); - parsers(snapdragon, options); + 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 ast = snapdragon.parse(pattern, options); - utils.define(ast, 'snapdragon', snapdragon); - ast.input = pattern; - return ast; - } + switch (ctorName(val)) { + case 'Symbol': return 'symbol'; + case 'Promise': return 'promise'; - return memoize('parse', pattern, options, parse); -}; + // Set, Map, WeakSet, WeakMap + case 'WeakMap': return 'weakmap'; + case 'WeakSet': return 'weakset'; + case 'Map': return 'map'; + case 'Set': return 'set'; -/** - * Compile the given `ast` or string with the given `options`. - * - * ```js - * var mm = require('micromatch'); - * mm.compile(ast[, options]); - * - * var ast = mm.parse('a/{b,c}/d'); - * console.log(mm.compile(ast)); - * // { options: { source: 'string' }, - * // state: {}, - * // compilers: - * // { eos: [Function], - * // noop: [Function], - * // bos: [Function], - * // brace: [Function], - * // 'brace.open': [Function], - * // text: [Function], - * // 'brace.close': [Function] }, - * // output: [ 'a/(b|c)/d' ], - * // ast: - * // { ... }, - * // parsingErrors: [] } - * ``` - * @param {Object|String} `ast` - * @param {Object} `options` - * @return {Object} Returns an object that has an `output` property with the compiled string. - * @api public - */ + // 8-bit typed arrays + case 'Int8Array': return 'int8array'; + case 'Uint8Array': return 'uint8array'; + case 'Uint8ClampedArray': return 'uint8clampedarray'; -micromatch.compile = function(ast, options) { - if (typeof ast === 'string') { - ast = micromatch.parse(ast, options); + // 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 memoize('compile', ast.input, options, function() { - var snapdragon = utils.instantiate(ast, options); - compilers(snapdragon, options); - return snapdragon.compile(ast, options); - }); -}; + if (isGeneratorObj(val)) { + return 'generator'; + } -/** - * Clear the regex cache. - * - * ```js - * mm.clearCache(); - * ``` - * @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'; + } -micromatch.clearCache = function() { - micromatch.cache.caches = {}; + // other + return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); }; -/** - * Returns true if the given value is effectively an empty string - */ - -function isEmptyString(val) { - return String(val) === '' || String(val) === './'; +function ctorName(val) { + return typeof val.constructor === 'function' ? val.constructor.name : null; } -/** - * Compose a matcher function with the given patterns. - * This allows matcher functions to be compiled once and - * called multiple times. - */ - -function compose(patterns, options, matcher) { - var matchers; +function isArray(val) { + if (Array.isArray) return Array.isArray(val); + return val instanceof Array; +} - return memoize('compose', String(patterns), options, function() { - return function(file) { - // delay composition until it's invoked the first time, - // after that it won't be called again - if (!matchers) { - matchers = []; - for (var i = 0; i < patterns.length; i++) { - matchers.push(matcher(patterns[i], options)); - } - } +function isError(val) { + return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); +} - var len = matchers.length; - while (len--) { - if (matchers[len](file) === true) { - return true; - } - } - return false; - }; - }); +function isDate(val) { + if (val instanceof Date) return true; + return typeof val.toDateString === 'function' + && typeof val.getDate === 'function' + && typeof val.setDate === 'function'; } -/** - * Memoize a generated regex or function. A unique key is generated - * from the `type` (usually method name), the `pattern`, and - * user-defined options. - */ +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 memoize(type, pattern, options, fn) { - var key = utils.createKey(type + '=' + pattern, options); +function isGeneratorFn(name, val) { + return ctorName(name) === 'GeneratorFunction'; +} - if (options && options.cache === false) { - return fn(pattern, options); - } +function isGeneratorObj(val) { + return typeof val.throw === 'function' + && typeof val.return === 'function' + && typeof val.next === 'function'; +} - if (cache.has(type, key)) { - return cache.get(type, key); +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; + } } - - var val = fn(pattern, options); - cache.set(type, key, val); - return val; + return false; } /** - * Expose compiler, parser and cache on `micromatch` - */ - -micromatch.compilers = compilers; -micromatch.parsers = parsers; -micromatch.caches = cache.caches; - -/** - * Expose `micromatch` - * @type {Function} + * If you need to support Safari 5-7 (8-10 yr-old browser), + * take a look at https://github.com/feross/is-buffer */ -module.exports = micromatch; +function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === 'function') { + return val.constructor.isBuffer(val); + } + return false; +} /***/ }), -/* 515 */ +/* 537 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - - -/** - * Module dependencies +/*! + * is-accessor-descriptor + * + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -var toRegex = __webpack_require__(516); -var unique = __webpack_require__(528); -var extend = __webpack_require__(525); -/** - * Local dependencies - */ -var compilers = __webpack_require__(529); -var parsers = __webpack_require__(544); -var Braces = __webpack_require__(554); -var utils = __webpack_require__(530); -var MAX_LENGTH = 1024 * 64; -var cache = {}; +var typeOf = __webpack_require__(538); -/** - * Convert the given `braces` pattern into a regex-compatible string. By default, only one string is generated for every input string. Set `options.expand` to true to return an array of patterns (similar to Bash or minimatch. Before using `options.expand`, it's recommended that you read the [performance notes](#performance)). - * - * ```js - * var braces = require('braces'); - * console.log(braces('{a,b,c}')); - * //=> ['(a|b|c)'] - * - * console.log(braces('{a,b,c}', {expand: true})); - * //=> ['a', 'b', 'c'] - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {String} - * @api public - */ +// accessor descriptor properties +var accessor = { + get: 'function', + set: 'function', + configurable: 'boolean', + enumerable: 'boolean' +}; -function braces(pattern, options) { - var key = utils.createKey(String(pattern), options); - var arr = []; +function isAccessorDescriptor(obj, prop) { + if (typeof prop === 'string') { + var val = Object.getOwnPropertyDescriptor(obj, prop); + return typeof val !== 'undefined'; + } - var disabled = options && options.cache === false; - if (!disabled && cache.hasOwnProperty(key)) { - return cache[key]; + if (typeOf(obj) !== 'object') { + return false; } - if (Array.isArray(pattern)) { - for (var i = 0; i < pattern.length; i++) { - arr.push.apply(arr, braces.create(pattern[i], options)); - } - } else { - arr = braces.create(pattern, options); + if (has(obj, 'value') || has(obj, 'writable')) { + return false; } - if (options && options.nodupes === true) { - arr = unique(arr); + if (!has(obj, 'get') || typeof obj.get !== 'function') { + return false; } - if (!disabled) { - cache[key] = arr; + // 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; } - return arr; -} -/** - * 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 [.optimize](#optimize) instead. - * - * ```js - * var 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 - */ + for (var key in obj) { + if (!accessor.hasOwnProperty(key)) { + continue; + } -braces.expand = function(pattern, options) { - return braces.create(pattern, extend({}, options, {expand: true})); -}; + if (typeOf(obj[key]) === accessor[key]) { + continue; + } -/** - * Expands a brace pattern into a regex-compatible, optimized string. This method is called by the main [braces](#braces) function by default. - * - * ```js - * var braces = require('braces'); - * console.log(braces.expand('a/{b,c}/d')); - * //=> ['a/(b|c)/d'] - * ``` - * @param {String} `pattern` Brace pattern - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ + if (typeof obj[key] !== 'undefined') { + return false; + } + } + return true; +} -braces.optimize = function(pattern, options) { - return braces.create(pattern, options); -}; +function has(obj, key) { + return {}.hasOwnProperty.call(obj, key); +} /** - * 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 - * var 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 + * Expose `isAccessorDescriptor` */ -braces.create = function(pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('expected a string'); - } - - var maxLength = (options && options.maxLength) || MAX_LENGTH; - if (pattern.length >= maxLength) { - throw new Error('expected pattern to be less than ' + maxLength + ' characters'); - } - - function create() { - if (pattern === '' || pattern.length < 3) { - return [pattern]; - } +module.exports = isAccessorDescriptor; - if (utils.isEmptySets(pattern)) { - return []; - } - if (utils.isQuotedString(pattern)) { - return [pattern.slice(1, -1)]; - } +/***/ }), +/* 538 */ +/***/ (function(module, exports) { - var proto = new Braces(options); - var result = !options || options.expand !== true - ? proto.optimize(pattern, options) - : proto.expand(pattern, options); +var toString = Object.prototype.toString; - // get the generated pattern(s) - var arr = result.output; +module.exports = function kindOf(val) { + if (val === void 0) return 'undefined'; + if (val === null) return 'null'; - // filter out empty strings if specified - if (options && options.noempty === true) { - arr = arr.filter(Boolean); - } + 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'; + } - // filter out duplicates if specified - if (options && options.nodupes === true) { - arr = unique(arr); - } + 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'; - Object.defineProperty(arr, 'result', { - enumerable: false, - value: result - }); + switch (ctorName(val)) { + case 'Symbol': return 'symbol'; + case 'Promise': return 'promise'; - return arr; - } + // Set, Map, WeakSet, WeakMap + case 'WeakMap': return 'weakmap'; + case 'WeakSet': return 'weakset'; + case 'Map': return 'map'; + case 'Set': return 'set'; - return memoize('create', pattern, options, create); -}; + // 8-bit typed arrays + case 'Int8Array': return 'int8array'; + case 'Uint8Array': return 'uint8array'; + case 'Uint8ClampedArray': return 'uint8clampedarray'; -/** - * Create a regular expression from the given string `pattern`. - * - * ```js - * var braces = require('braces'); - * - * console.log(braces.makeRe('id-{200..300}')); - * //=> /^(?:id-(20[0-9]|2[1-9][0-9]|300))$/ - * ``` - * @param {String} `pattern` The pattern to convert to regex. - * @param {Object} `options` - * @return {RegExp} - * @api public - */ + // 16-bit typed arrays + case 'Int16Array': return 'int16array'; + case 'Uint16Array': return 'uint16array'; -braces.makeRe = function(pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('expected a string'); + // 32-bit typed arrays + case 'Int32Array': return 'int32array'; + case 'Uint32Array': return 'uint32array'; + case 'Float32Array': return 'float32array'; + case 'Float64Array': return 'float64array'; } - var maxLength = (options && options.maxLength) || MAX_LENGTH; - if (pattern.length >= maxLength) { - throw new Error('expected pattern to be less than ' + maxLength + ' characters'); + if (isGeneratorObj(val)) { + return 'generator'; } - function makeRe() { - var arr = braces(pattern, options); - var opts = extend({strictErrors: false}, options); - return toRegex(arr, opts); + // Non-plain objects + type = toString.call(val); + switch (type) { + case '[object Object]': return 'object'; + // iterators + case '[object Map Iterator]': return 'mapiterator'; + case '[object Set Iterator]': return 'setiterator'; + case '[object String Iterator]': return 'stringiterator'; + case '[object Array Iterator]': return 'arrayiterator'; } - return memoize('makeRe', pattern, options, makeRe); -}; - -/** - * Parse the given `str` with the given `options`. - * - * ```js - * var braces = require('braces'); - * var ast = braces.parse('a/{b,c}/d'); - * console.log(ast); - * // { type: 'root', - * // errors: [], - * // input: 'a/{b,c}/d', - * // nodes: - * // [ { type: 'bos', val: '' }, - * // { type: 'text', val: 'a/' }, - * // { type: 'brace', - * // nodes: - * // [ { type: 'brace.open', val: '{' }, - * // { type: 'text', val: 'b,c' }, - * // { type: 'brace.close', val: '}' } ] }, - * // { type: 'text', val: '/d' }, - * // { type: 'eos', val: '' } ] } - * ``` - * @param {String} `pattern` Brace pattern to parse - * @param {Object} `options` - * @return {Object} Returns an AST - * @api public - */ - -braces.parse = function(pattern, options) { - var proto = new Braces(options); - return proto.parse(pattern, options); -}; - -/** - * Compile the given `ast` or string with the given `options`. - * - * ```js - * var braces = require('braces'); - * var ast = braces.parse('a/{b,c}/d'); - * console.log(braces.compile(ast)); - * // { options: { source: 'string' }, - * // state: {}, - * // compilers: - * // { eos: [Function], - * // noop: [Function], - * // bos: [Function], - * // brace: [Function], - * // 'brace.open': [Function], - * // text: [Function], - * // 'brace.close': [Function] }, - * // output: [ 'a/(b|c)/d' ], - * // ast: - * // { ... }, - * // parsingErrors: [] } - * ``` - * @param {Object|String} `ast` AST from [.parse](#parse). If a string is passed it will be parsed first. - * @param {Object} `options` - * @return {Object} Returns an object that has an `output` property with the compiled string. - * @api public - */ - -braces.compile = function(ast, options) { - var proto = new Braces(options); - return proto.compile(ast, options); + // other + return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); }; -/** - * Clear the regex cache. - * - * ```js - * braces.clearCache(); - * ``` - * @api public - */ - -braces.clearCache = function() { - cache = braces.cache = {}; -}; +function ctorName(val) { + return typeof val.constructor === 'function' ? val.constructor.name : null; +} -/** - * Memoize a generated regex or function. A unique key is generated - * from the method name, pattern, and user-defined options. Set - * options.memoize to false to disable. - */ +function isArray(val) { + if (Array.isArray) return Array.isArray(val); + return val instanceof Array; +} -function memoize(type, pattern, options, fn) { - var key = utils.createKey(type + ':' + pattern, options); - var disabled = options && options.cache === false; - if (disabled) { - braces.clearCache(); - return fn(pattern, options); - } +function isError(val) { + return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); +} - if (cache.hasOwnProperty(key)) { - return cache[key]; - } +function isDate(val) { + if (val instanceof Date) return true; + return typeof val.toDateString === 'function' + && typeof val.getDate === 'function' + && typeof val.setDate === 'function'; +} - var res = fn(pattern, options); - cache[key] = res; - return res; +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'; } -/** - * Expose `Braces` constructor and methods - * @type {Function} - */ +function isGeneratorObj(val) { + return typeof val.throw === 'function' + && typeof val.return === 'function' + && typeof val.next === 'function'; +} -braces.Braces = Braces; -braces.compilers = compilers; -braces.parsers = parsers; -braces.cache = cache; +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; +} /** - * Expose `braces` - * @type {Function} + * If you need to support Safari 5-7 (8-10 yr-old browser), + * take a look at https://github.com/feross/is-buffer */ -module.exports = braces; +function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === 'function') { + return val.constructor.isBuffer(val); + } + return false; +} /***/ }), -/* 516 */ +/* 539 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - - -var define = __webpack_require__(517); -var extend = __webpack_require__(525); -var not = __webpack_require__(527); -var MAX_LENGTH = 1024 * 64; - -/** - * Session cache +/*! + * is-data-descriptor + * + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. */ -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); -}; +var typeOf = __webpack_require__(540); -/** - * 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 isDataDescriptor(obj, prop) { + // data descriptor properties + var data = { + configurable: 'boolean', + enumerable: 'boolean', + writable: 'boolean' + }; -function makeRe(pattern, options) { - if (pattern instanceof RegExp) { - return pattern; + if (typeOf(obj) !== 'object') { + return false; } - if (typeof pattern !== 'string') { - throw new TypeError('expected a string'); + if (typeof prop === 'string') { + var val = Object.getOwnPropertyDescriptor(obj, prop); + return typeof val !== 'undefined'; } - if (pattern.length > MAX_LENGTH) { - throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); + if (!('value' in obj) && !('writable' in obj)) { + return false; } - var key = pattern; - // do this before shallow cloning options, it's a lot faster - if (!options || (options && options.cache !== false)) { - key = createKey(pattern, options); + for (var key in obj) { + if (key === 'value') continue; - if (cache.hasOwnProperty(key)) { - return cache[key]; + if (!data.hasOwnProperty(key)) { + continue; } - } - var opts = extend({}, options); - if (opts.contains === true) { - if (opts.negate === true) { - opts.strictNegate = false; - } else { - opts.strict = false; + if (typeOf(obj[key]) === data[key]) { + continue; } - } - if (opts.strict === false) { - opts.strictOpen = false; - opts.strictClose = false; + if (typeof obj[key] !== 'undefined') { + return false; + } } + return true; +}; - 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'; +/***/ }), +/* 540 */ +/***/ (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'; } - 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; - } + 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'; - try { - regex = new RegExp('^' + pattern.replace(/(\W)/g, '\\$1') + '$'); - } catch (err) { - regex = /.^/; //<= match nothing - } + 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 (opts.cache !== false) { - cacheRegex(regex, key, pattern, opts); + if (isGeneratorObj(val)) { + return 'generator'; } - return regex; + + // 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; } -/** - * 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 isArray(val) { + if (Array.isArray) return Array.isArray(val); + return val instanceof Array; +} -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; +function isError(val) { + return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); } -/** - * 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 isDate(val) { + if (val instanceof Date) return true; + return typeof val.toDateString === 'function' + && typeof val.getDate === 'function' + && typeof val.setDate === 'function'; +} -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]); +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 key; + return false; } /** - * Expose `makeRe` + * If you need to support Safari 5-7 (8-10 yr-old browser), + * take a look at https://github.com/feross/is-buffer */ -module.exports.makeRe = makeRe; +function isBuffer(val) { + if (val.constructor && typeof val.constructor.isBuffer === 'function') { + return val.constructor.isBuffer(val); + } + return false; +} /***/ }), -/* 517 */ +/* 541 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * define-property - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ +var isExtendable = __webpack_require__(542); +var assignSymbols = __webpack_require__(544); -var isDescriptor = __webpack_require__(518); - -module.exports = function defineProperty(obj, prop, val) { - if (typeof obj !== 'object' && typeof obj !== 'function') { - throw new TypeError('expected an object or function.'); +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 (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); +function assign(a, b) { + for (var key in b) { + if (hasOwn(b, key)) { + a[key] = b[key]; + } } +} - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); +function isString(val) { + return (val && typeof val === 'string'); +} + +function toObject(str) { + var obj = {}; + for (var i in str) { + obj[i] = str[i]; } + return obj; +} - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); -}; +function isObject(val) { + return (val && typeof val === 'object') || isExtendable(val); +} + +/** + * Returns true if the given `key` is an own property of `obj`. + */ + +function hasOwn(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} + +function isEnum(obj, key) { + return Object.prototype.propertyIsEnumerable.call(obj, key); +} /***/ }), -/* 518 */ +/* 542 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-descriptor + * is-extendable * * Copyright (c) 2015-2017, Jon Schlinkert. * Released under the MIT License. @@ -58204,181 +61972,64 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(519); -var isAccessor = __webpack_require__(520); -var isData = __webpack_require__(523); +var isPlainObject = __webpack_require__(543); -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; - } - if ('get' in obj) { - return isAccessor(obj, key); - } - return isData(obj, key); +module.exports = function isExtendable(val) { + return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); }; /***/ }), -/* 519 */ -/***/ (function(module, exports) { - -var toString = Object.prototype.toString; +/* 543 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Get the native `typeof` a value. +"use strict"; +/*! + * is-plain-object * - * @param {*} `val` - * @return {*} Native javascript type - */ - -module.exports = function kindOf(val) { - var type = typeof val; - - // primitivies - if (type === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (type === 'string' || val instanceof String) { - return 'string'; - } - if (type === 'number' || val instanceof Number) { - return 'number'; - } - - // functions - if (type === 'function' || val instanceof Function) { - if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { - return 'generatorfunction'; - } - return 'function'; - } - - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } - - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } - - // other objects - type = toString.call(val); - - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } - if (type === '[object Promise]') { - return 'promise'; - } - - // buffer - if (isBuffer(val)) { - return 'buffer'; - } - - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - - if (type === '[object Map Iterator]') { - return 'mapiterator'; - } - if (type === '[object Set Iterator]') { - return 'setiterator'; - } - if (type === '[object String Iterator]') { - return 'stringiterator'; - } - if (type === '[object Array Iterator]') { - return 'arrayiterator'; - } - - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; - } - if (type === '[object Float32Array]') { - return 'float32array'; - } - if (type === '[object Float64Array]') { - return 'float64array'; - } + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ - // must be a plain object - return 'object'; -}; -/** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer - */ -function isBuffer(val) { - return val.constructor - && typeof val.constructor.isBuffer === 'function' - && val.constructor.isBuffer(val); +var isObject = __webpack_require__(534); + +function isObjectObject(o) { + return isObject(o) === true + && Object.prototype.toString.call(o) === '[object Object]'; } +module.exports = function isPlainObject(o) { + var ctor,prot; + + if (isObjectObject(o) === false) return false; + + // If has modified constructor + ctor = o.constructor; + if (typeof ctor !== 'function') return false; + + // If has modified prototype + prot = ctor.prototype; + if (isObjectObject(prot) === false) return false; + + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } + + // Most likely a plain Object + return true; +}; + /***/ }), -/* 520 */ +/* 544 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-accessor-descriptor + * assign-symbols * * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. @@ -58386,409 +62037,264 @@ function isBuffer(val) { -var typeOf = __webpack_require__(521); - -// 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; +module.exports = function(receiver, objects) { + if (receiver === null || typeof receiver === 'undefined') { + throw new TypeError('expected first argument to be an object.'); } - if (has(obj, 'value') || has(obj, 'writable')) { - return false; + if (typeof objects === 'undefined' || typeof Symbol === 'undefined') { + return receiver; } - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; + if (typeof Object.getOwnPropertySymbols !== 'function') { + return receiver; } - // tldr: it's valid to have "set" be undefined - // "set" might be undefined if `Object.getOwnPropertyDescriptor` - // was used to get the value, and only `get` was defined by the user - if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { - return false; - } + var isEnumerable = Object.prototype.propertyIsEnumerable; + var target = Object(receiver); + var len = arguments.length, i = 0; - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; - } + while (++i < len) { + var provider = Object(arguments[i]); + var names = Object.getOwnPropertySymbols(provider); - if (typeOf(obj[key]) === accessor[key]) { - continue; - } + for (var j = 0; j < names.length; j++) { + var key = names[j]; - if (typeof obj[key] !== 'undefined') { - return false; + if (isEnumerable.call(provider, key)) { + target[key] = provider[key]; + } } } - return true; -} + return target; +}; -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} -/** - * Expose `isAccessorDescriptor` - */ +/***/ }), +/* 545 */ +/***/ (function(module, exports, __webpack_require__) { -module.exports = isAccessorDescriptor; +"use strict"; -/***/ }), -/* 521 */ -/***/ (function(module, exports, __webpack_require__) { +var extend = __webpack_require__(546); +var safe = __webpack_require__(527); -var isBuffer = __webpack_require__(522); -var toString = Object.prototype.toString; +/** + * 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)); +} /** - * Get the native `typeof` a value. + * Create a regex-compatible string from the given `pattern` and `options`. * - * @param {*} `val` - * @return {*} Native javascript type + * ```js + & var not = require('regex-not'); + & console.log(not.create('foo')); + & //=> '^(?:(?!^(?:foo)$).)*$' + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {String} + * @api public */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; +toRegex.create = function(pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('expected a string'); } - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; + var opts = extend({}, options); + if (opts.contains === true) { + opts.strictNegate = false; } - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; - } + var open = opts.strictOpen !== false ? '^' : ''; + var close = opts.strictClose !== false ? '$' : ''; + var endChar = opts.endChar ? opts.endChar : '+'; + var str = pattern; - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; + if (opts.strictNegate === false) { + str = '(?:(?!(?:' + pattern + ')).)' + endChar; + } else { + str = '(?:(?!^(?:' + pattern + ')$).)' + endChar; } - if (val instanceof Date) { - return 'date'; + + var res = open + str + close; + if (opts.safe === true && safe(res) === false) { + throw new Error('potentially unsafe regular expression: ' + res); } - // other objects - var type = toString.call(val); + return res; +}; - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; - } +/** + * Expose `toRegex` + */ - // buffer - if (isBuffer(val)) { - return 'buffer'; - } +module.exports = toRegex; - // es6: Map, WeakMap, Set, WeakSet - if (type === '[object Set]') { - return 'set'; - } - if (type === '[object WeakSet]') { - return 'weakset'; - } - if (type === '[object Map]') { - return 'map'; - } - if (type === '[object WeakMap]') { - return 'weakmap'; - } - if (type === '[object Symbol]') { - return 'symbol'; - } - // typed arrays - if (type === '[object Int8Array]') { - return 'int8array'; - } - if (type === '[object Uint8Array]') { - return 'uint8array'; - } - if (type === '[object Uint8ClampedArray]') { - return 'uint8clampedarray'; - } - if (type === '[object Int16Array]') { - return 'int16array'; - } - if (type === '[object Uint16Array]') { - return 'uint16array'; - } - if (type === '[object Int32Array]') { - return 'int32array'; - } - if (type === '[object Uint32Array]') { - return 'uint32array'; +/***/ }), +/* 546 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var isExtendable = __webpack_require__(547); +var assignSymbols = __webpack_require__(544); + +module.exports = Object.assign || function(obj/*, objects*/) { + if (obj === null || typeof obj === 'undefined') { + throw new TypeError('Cannot convert undefined or null to object'); } - if (type === '[object Float32Array]') { - return 'float32array'; + if (!isObject(obj)) { + obj = {}; } - if (type === '[object Float64Array]') { - return 'float64array'; + 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); + } } - - // must be a plain object - return 'object'; + return obj; }; +function assign(a, b) { + for (var key in b) { + if (hasOwn(b, key)) { + a[key] = b[key]; + } + } +} -/***/ }), -/* 522 */ -/***/ (function(module, exports) { +function isString(val) { + return (val && typeof val === 'string'); +} -/*! - * Determine if an object is a Buffer - * - * @author Feross Aboukhadijeh - * @license MIT - */ +function toObject(str) { + var obj = {}; + for (var i in str) { + obj[i] = str[i]; + } + return obj; +} -// 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) +function isObject(val) { + return (val && typeof val === 'object') || isExtendable(val); } -function isBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +/** + * Returns true if the given `key` is an own property of `obj`. + */ + +function hasOwn(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); } -// 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)) +function isEnum(obj, key) { + return Object.prototype.propertyIsEnumerable.call(obj, key); } /***/ }), -/* 523 */ +/* 547 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * is-data-descriptor + * is-extendable * - * 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__(524); +var isPlainObject = __webpack_require__(543); -// data descriptor properties -var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' +module.exports = function isExtendable(val) { + return isPlainObject(val) || typeof val === 'function' || Array.isArray(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'; - } - - 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; -} - -/** - * Expose `isDataDescriptor` - */ - -module.exports = isDataDescriptor; - /***/ }), -/* 524 */ +/* 548 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(522); -var toString = Object.prototype.toString; - -/** - * Get the native `typeof` a value. +"use strict"; +/*! + * array-unique * - * @param {*} `val` - * @return {*} Native javascript type + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. */ -module.exports = function kindOf(val) { - // primitivies - if (typeof val === 'undefined') { - return 'undefined'; - } - if (val === null) { - return 'null'; - } - if (val === true || val === false || val instanceof Boolean) { - return 'boolean'; - } - if (typeof val === 'string' || val instanceof String) { - return 'string'; - } - if (typeof val === 'number' || val instanceof Number) { - return 'number'; - } - // functions - if (typeof val === 'function' || val instanceof Function) { - return 'function'; - } - // array - if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { - return 'array'; +module.exports = function unique(arr) { + if (!Array.isArray(arr)) { + throw new TypeError('array-unique expects an array.'); } - // check for instances of RegExp and Date before calling `toString` - if (val instanceof RegExp) { - return 'regexp'; - } - if (val instanceof Date) { - return 'date'; - } + var len = arr.length; + var i = -1; - // other objects - var type = toString.call(val); + while (i++ < len) { + var j = i + 1; - if (type === '[object RegExp]') { - return 'regexp'; - } - if (type === '[object Date]') { - return 'date'; - } - if (type === '[object Arguments]') { - return 'arguments'; - } - if (type === '[object Error]') { - return 'error'; + for (; j < arr.length; ++j) { + if (arr[i] === arr[j]) { + arr.splice(j--, 1); + } + } } + return arr; +}; - // buffer - if (isBuffer(val)) { - return 'buffer'; +module.exports.immutable = function uniqueImmutable(arr) { + if (!Array.isArray(arr)) { + throw new TypeError('array-unique expects an array.'); } - // 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'; - } + var arrLen = arr.length; + var newArr = new Array(arrLen); - // 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'; + for (var i = 0; i < arrLen; i++) { + newArr[i] = arr[i]; } - // must be a plain object - return 'object'; + return module.exports(newArr); }; /***/ }), -/* 525 */ +/* 549 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(526); +var isObject = __webpack_require__(550); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -58822,7 +62328,7 @@ function hasOwn(obj, key) { /***/ }), -/* 526 */ +/* 550 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58842,136 +62348,13 @@ module.exports = function isExtendable(val) { /***/ }), -/* 527 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var extend = __webpack_require__(525); - -/** - * 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 && 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 && opts.strictNegate === false) { - str = '(?:(?!(?:' + pattern + ')).)' + endChar; - } else { - str = '(?:(?!^(?:' + pattern + ')$).)' + endChar; - } - - return open + str + close; -}; - -/** - * Expose `toRegex` - */ - -module.exports = toRegex; - - -/***/ }), -/* 528 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * array-unique - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -module.exports = function unique(arr) { - if (!Array.isArray(arr)) { - throw new TypeError('array-unique expects an array.'); - } - - var len = arr.length; - var i = -1; - - while (i++ < len) { - var j = i + 1; - - for (; j < arr.length; ++j) { - if (arr[i] === arr[j]) { - arr.splice(j--, 1); - } - } - } - return arr; -}; - -module.exports.immutable = function uniqueImmutable(arr) { - if (!Array.isArray(arr)) { - throw new TypeError('array-unique expects an array.'); - } - - var arrLen = arr.length; - var newArr = new Array(arrLen); - - for (var i = 0; i < arrLen; i++) { - newArr[i] = arr[i]; - } - - return module.exports(newArr); -}; - - -/***/ }), -/* 529 */ +/* 551 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(530); +var utils = __webpack_require__(552); module.exports = function(braces, options) { braces.compiler @@ -59254,25 +62637,25 @@ function hasQueue(node) { /***/ }), -/* 530 */ +/* 552 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var splitString = __webpack_require__(531); +var splitString = __webpack_require__(553); var utils = module.exports; /** * Module dependencies */ -utils.extend = __webpack_require__(525); -utils.flatten = __webpack_require__(537); -utils.isObject = __webpack_require__(535); -utils.fillRange = __webpack_require__(538); -utils.repeat = __webpack_require__(543); -utils.unique = __webpack_require__(528); +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); utils.define = function(obj, key, val) { Object.defineProperty(obj, key, { @@ -59604,7 +62987,7 @@ utils.escapeRegex = function(str) { /***/ }), -/* 531 */ +/* 553 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59617,7 +63000,7 @@ utils.escapeRegex = function(str) { -var extend = __webpack_require__(532); +var extend = __webpack_require__(554); module.exports = function(str, options, fn) { if (typeof str !== 'string') { @@ -59782,14 +63165,14 @@ function keepEscaping(opts, str, idx) { /***/ }), -/* 532 */ +/* 554 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(533); -var assignSymbols = __webpack_require__(536); +var isExtendable = __webpack_require__(555); +var assignSymbols = __webpack_require__(544); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -59849,7 +63232,7 @@ function isEnum(obj, key) { /***/ }), -/* 533 */ +/* 555 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59862,7 +63245,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(534); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -59870,117 +63253,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 534 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-plain-object - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var isObject = __webpack_require__(535); - -function isObjectObject(o) { - return isObject(o) === true - && Object.prototype.toString.call(o) === '[object Object]'; -} - -module.exports = function isPlainObject(o) { - var ctor,prot; - - if (isObjectObject(o) === false) return false; - - // If has modified constructor - ctor = o.constructor; - if (typeof ctor !== 'function') return false; - - // If has modified prototype - prot = ctor.prototype; - if (isObjectObject(prot) === false) return false; - - // If constructor does not have an Object-specific method - if (prot.hasOwnProperty('isPrototypeOf') === false) { - return false; - } - - // Most likely a plain Object - return true; -}; - - -/***/ }), -/* 535 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * isobject - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -module.exports = function isObject(val) { - return val != null && typeof val === 'object' && Array.isArray(val) === false; -}; - - -/***/ }), -/* 536 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * assign-symbols - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - - - -module.exports = function(receiver, objects) { - if (receiver === null || typeof receiver === 'undefined') { - throw new TypeError('expected first argument to be an object.'); - } - - if (typeof objects === 'undefined' || typeof Symbol === 'undefined') { - return receiver; - } - - if (typeof Object.getOwnPropertySymbols !== 'function') { - return receiver; - } - - var isEnumerable = Object.prototype.propertyIsEnumerable; - var target = Object(receiver); - var len = arguments.length, i = 0; - - while (++i < len) { - var provider = Object(arguments[i]); - var names = Object.getOwnPropertySymbols(provider); - - for (var j = 0; j < names.length; j++) { - var key = names[j]; - - if (isEnumerable.call(provider, key)) { - target[key] = provider[key]; - } - } - } - return target; -}; - - -/***/ }), -/* 537 */ +/* 556 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60009,7 +63282,7 @@ function flat(arr, res) { /***/ }), -/* 538 */ +/* 557 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60022,11 +63295,11 @@ function flat(arr, res) { -var util = __webpack_require__(111); -var isNumber = __webpack_require__(539); -var extend = __webpack_require__(525); -var repeat = __webpack_require__(541); -var toRegex = __webpack_require__(542); +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. @@ -60224,7 +63497,7 @@ module.exports = fillRange; /***/ }), -/* 539 */ +/* 558 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60237,7 +63510,7 @@ module.exports = fillRange; -var typeOf = __webpack_require__(540); +var typeOf = __webpack_require__(559); module.exports = function isNumber(num) { var type = typeOf(num); @@ -60253,10 +63526,10 @@ module.exports = function isNumber(num) { /***/ }), -/* 540 */ +/* 559 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(522); +var isBuffer = __webpack_require__(560); var toString = Object.prototype.toString; /** @@ -60369,13 +63642,40 @@ module.exports = function kindOf(val) { return 'float64array'; } - // must be a plain object - return 'object'; -}; + // must be a plain object + return 'object'; +}; + + +/***/ }), +/* 560 */ +/***/ (function(module, exports) { + +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +// 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) +} + +function isBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} + +// 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)) +} /***/ }), -/* 541 */ +/* 561 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60452,7 +63752,7 @@ function repeat(str, num) { /***/ }), -/* 542 */ +/* 562 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60465,8 +63765,8 @@ function repeat(str, num) { -var repeat = __webpack_require__(541); -var isNumber = __webpack_require__(539); +var repeat = __webpack_require__(561); +var isNumber = __webpack_require__(558); var cache = {}; function toRegexRange(min, max, options) { @@ -60753,7 +64053,7 @@ module.exports = toRegexRange; /***/ }), -/* 543 */ +/* 563 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60778,14 +64078,14 @@ module.exports = function repeat(ele, num) { /***/ }), -/* 544 */ +/* 564 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Node = __webpack_require__(545); -var utils = __webpack_require__(530); +var Node = __webpack_require__(565); +var utils = __webpack_require__(552); /** * Braces parsers @@ -61043,157 +64343,653 @@ module.exports = function(braces, options) { var prev = this.prev(); var val = m[0]; - if (isInside && prev.type === 'brace') { - prev.text = prev.text || ''; - prev.text += val; - } + if (isInside && prev.type === 'brace') { + prev.text = prev.text || ''; + prev.text += val; + } + + return pos(new Node({ + type: 'text', + multiplier: 0, + val: val + })); + }) + + /** + * Text + */ + + .set('text', function() { + var isInside = this.isInside('brace'); + var pos = this.position(); + var m = this.match(/^((?!\\)[^${}[\]])+/); + if (!m) return; + + var prev = this.prev(); + var val = m[0]; + + if (isInside && prev.type === 'brace') { + prev.text = prev.text || ''; + prev.text += val; + } + + var node = pos(new Node({ + type: 'text', + multiplier: 1, + val: val + })); + + return concatNodes.call(this, pos, node, prev, options); + }); +}; + +/** + * Returns true if the character is an extglob character. + */ + +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} + */ + +function concatNodes(pos, node, parent, options) { + node.orig = node.val; + var prev = this.prev(); + var last = utils.last(prev.nodes); + var isEscaped = false; + + if (node.val.length > 1) { + var a = node.val.charAt(0); + var b = node.val.slice(-1); + + isEscaped = (a === '"' && b === '"') + || (a === "'" && b === "'") + || (a === '`' && b === '`'); + } + + if (isEscaped && options.unescape !== false) { + node.val = node.val.slice(1, node.val.length - 1); + node.escaped = true; + } + + 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 = ''; + } + + var simpleText = last.type === 'text' + && last.multiplier === 1 + && node.multiplier === 1 + && node.val; + + if (simpleText) { + last.val += node.val; + return; + } + + prev.push(node); +} + + +/***/ }), +/* 565 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var isObject = __webpack_require__(534); +var define = __webpack_require__(566); +var utils = __webpack_require__(567); +var ownNames; + +/** + * 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 + */ + +function Node(val, type, parent) { + if (typeof type !== 'string') { + parent = type; + type = null; + } + + define(this, 'parent', parent); + define(this, 'isNode', true); + define(this, 'expect', null); + + 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; + } +} + +/** + * 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 + */ + +Node.isNode = function(node) { + return utils.isNode(node); +}; + +/** + * 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 + */ + +Node.prototype.define = function(name, val) { + define(this, name, val); + return this; +}; + +/** + * 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 + */ + +Node.prototype.isEmpty = function(fn) { + return utils.isEmpty(this, fn); +}; + +/** + * 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 + */ + +Node.prototype.push = 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.push(node); +}; + +/** + * 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 + */ + +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); +}; + +/** + * 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 + */ + +Node.prototype.pop = function() { + return this.nodes && this.nodes.pop(); +}; + +/** + * 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 + */ + +Node.prototype.shift = function() { + return this.nodes && this.nodes.shift(); +}; + +/** + * 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; +}; + +/** + * 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. + * + * ```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 + */ + +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); +}; + +/** + * 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 + */ + +Node.prototype.hasType = function(type) { + return utils.hasType(this, type); +}; + +/** + * 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; + } +}); + +/** + * 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 + */ + +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; + } +}); + +/** + * 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 + */ + +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; + } +}); + +/** + * 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 + */ - return pos(new Node({ - type: 'text', - multiplier: 0, - val: val - })); - }) +Object.defineProperty(Node.prototype, 'first', { + get: function() { + return this.nodes ? this.nodes[0] : null; + } +}); - /** - * Text - */ +/** + * 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 + */ - .set('text', function() { - var isInside = this.isInside('brace'); - var pos = this.position(); - var m = this.match(/^((?!\\)[^${}[\]])+/); - if (!m) return; +Object.defineProperty(Node.prototype, 'last', { + get: function() { + return this.nodes ? utils.last(this.nodes) : null; + } +}); - var prev = this.prev(); - var 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 (isInside && prev.type === 'brace') { - prev.text = prev.text || ''; - prev.text += val; - } +Object.defineProperty(Node.prototype, 'scope', { + get: function() { + if (this.isScope !== true) { + return this.parent ? this.parent.scope : this; + } + return this; + } +}); - var node = pos(new Node({ - type: 'text', - multiplier: 1, - val: val - })); +/** + * Get own property names from Node prototype, but only the + * first time `Node` is instantiated + */ - return concatNodes.call(this, pos, node, prev, options); - }); -}; +function lazyKeys() { + if (!ownNames) { + ownNames = Object.getOwnPropertyNames(Node.prototype); + } +} /** - * Returns true if the character is an extglob character. + * Simplified assertion. Throws an error is `val` is falsey. */ -function isExtglobChar(ch) { - return ch === '!' || ch === '@' || ch === '*' || ch === '?' || ch === '+'; +function assert(val, message) { + if (!val) throw new Error(message); } /** - * Combine text nodes, and calculate empty sets (`{,,}`) - * @param {Function} `pos` Function to calculate node position - * @param {Object} `node` AST node - * @return {Object} + * Expose `Node` */ -function concatNodes(pos, node, parent, options) { - node.orig = node.val; - var prev = this.prev(); - var last = utils.last(prev.nodes); - var isEscaped = false; +exports = module.exports = Node; - if (node.val.length > 1) { - var a = node.val.charAt(0); - var b = node.val.slice(-1); - isEscaped = (a === '"' && b === '"') - || (a === "'" && b === "'") - || (a === '`' && b === '`'); - } +/***/ }), +/* 566 */ +/***/ (function(module, exports, __webpack_require__) { - if (isEscaped && options.unescape !== false) { - node.val = node.val.slice(1, node.val.length - 1); - node.escaped = true; - } +"use strict"; +/*! + * define-property + * + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. + */ - 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 = ''; + +var isDescriptor = __webpack_require__(535); + +module.exports = function defineProperty(obj, prop, val) { + if (typeof obj !== 'object' && typeof obj !== 'function') { + throw new TypeError('expected an object or function.'); } - var simpleText = last.type === 'text' - && last.multiplier === 1 - && node.multiplier === 1 - && node.val; + if (typeof prop !== 'string') { + throw new TypeError('expected `prop` to be a string.'); + } - if (simpleText) { - last.val += node.val; - return; + if (isDescriptor(val) && ('set' in val || 'get' in val)) { + return Object.defineProperty(obj, prop, val); } - prev.push(node); -} + return Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: val + }); +}; /***/ }), -/* 545 */ +/* 567 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(535); -var define = __webpack_require__(546); -var utils = __webpack_require__(553); -var ownNames; - -/** - * 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 - */ - -function Node(val, type, parent) { - if (typeof type !== 'string') { - parent = type; - type = null; - } - - define(this, 'parent', parent); - define(this, 'isNode', true); - define(this, 'expect', null); - - 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; - } -} +var typeOf = __webpack_require__(559); +var utils = module.exports; /** * Returns true if the given value is a node. @@ -61201,3874 +64997,3545 @@ function Node(val, type, parent) { * ```js * var Node = require('snapdragon-node'); * var node = new Node({type: 'foo'}); - * console.log(Node.isNode(node)); //=> true - * console.log(Node.isNode({})); //=> false + * console.log(utils.isNode(node)); //=> true + * console.log(utils.isNode({})); //=> false * ``` - * @param {Object} `node` + * @param {Object} `node` Instance of [snapdragon-node][] * @returns {Boolean} * @api public */ -Node.isNode = function(node) { - return utils.isNode(node); +utils.isNode = function(node) { + return typeOf(node) === 'object' && node.isNode === true; }; /** - * Define a non-enumberable property on the node instance. - * Useful for adding properties that shouldn't be extended - * or visible during debugging. + * Emit an empty string for the given `node`. * * ```js - * var node = new Node(); - * node.define('foo', 'something non-enumerable'); + * // do nothing for beginning-of-string + * snapdragon.compiler.set('bos', utils.noop); * ``` - * @param {String} `name` - * @param {any} `val` - * @return {Object} returns the node instance + * @param {Object} `node` Instance of [snapdragon-node][] + * @returns {undefined} * @api public */ -Node.prototype.define = function(name, val) { - define(this, name, val); - return this; +utils.noop = function(node) { + append(this, '', node); }; /** - * Returns true if `node.val` is an empty string, or `node.nodes` does - * not contain any non-empty text nodes. + * Appdend `node.val` to `compiler.output`, exactly as it was created + * by the parser. * * ```js - * var node = new Node({type: 'text'}); - * node.isEmpty(); //=> true - * node.val = 'foo'; - * node.isEmpty(); //=> false + * snapdragon.compiler.set('text', utils.identity); * ``` - * @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} + * @param {Object} `node` Instance of [snapdragon-node][] + * @returns {undefined} * @api public */ -Node.prototype.isEmpty = function(fn) { - return utils.isEmpty(this, fn); +utils.identity = function(node) { + append(this, node.val, node); }; /** - * Given node `foo` and node `bar`, push node `bar` onto `foo.nodes`, and - * set `foo` as `bar.parent`. + * 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 - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * foo.push(bar); + * snapdragon.compiler + * .set('i', function(node) { + * this.mapVisit(node); + * }) + * .set('i.open', utils.append('')) + * .set('i.close', utils.append('')) * ``` - * @param {Object} `node` - * @return {Number} Returns the length of `node.nodes` + * @param {Object} `node` Instance of [snapdragon-node][] + * @returns {Function} Returns a compiler middleware function. * @api public */ -Node.prototype.push = 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.push(node); +utils.append = function(val) { + return function(node) { + append(this, val, node); + }; }; /** - * Given node `foo` and node `bar`, unshift node `bar` onto `foo.nodes`, and - * set `foo` as `bar.parent`. + * 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 - * var foo = new Node({type: 'foo'}); - * var bar = new Node({type: 'bar'}); - * foo.unshift(bar); + * utils.toNoop(node); + * // convert `node.nodes` to the given value instead of deleting it + * utils.toNoop(node, []); * ``` - * @param {Object} `node` - * @return {Number} Returns the length of `node.nodes` + * @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.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); +utils.toNoop = function(node, nodes) { + if (nodes) { + node.nodes = nodes; + } else { + delete node.nodes; + node.type = 'text'; + node.val = ''; + } }; /** - * Pop a node from `node.nodes`. + * 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 - * 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 + * snapdragon.compiler.set('i', function(node) { + * utils.visit(node, function(childNode) { + * // do stuff with "childNode" + * return childNode; + * }); + * }); * ``` - * @return {Number} Returns the popped `node` + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {Function} `fn` + * @return {Object} returns the node after recursively visiting all child nodes. * @api public */ -Node.prototype.pop = function() { - return this.nodes && this.nodes.pop(); +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; }; /** - * Shift a node from `node.nodes`. + * Map [visit](#visit) the given `fn` over `node.nodes`. This is called by + * [visit](#visit), use this method if you do not want `fn` to be called on + * the first node. * * ```js - * var 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 + * snapdragon.compiler.set('i', function(node) { + * utils.mapVisit(node, function(childNode) { + * // do stuff with "childNode" + * return childNode; + * }); + * }); * ``` - * @return {Object} Returns the shifted `node` + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {Object} `options` + * @param {Function} `fn` + * @return {Object} returns the node * @api public */ -Node.prototype.shift = function() { - return this.nodes && this.nodes.shift(); +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; }; /** - * Remove `node` from `node.nodes`. + * Unshift an `*.open` node onto `node.nodes`. * * ```js - * node.remove(childNode); + * 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` - * @return {Object} Returns the removed node. + * @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 */ -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); +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 = ''; } - return null; + + 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; }; /** - * 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. + * Push a `*.close` node onto `node.nodes`. * * ```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) + * var Node = require('snapdragon-node'); + * snapdragon.parser.set('brace', function(node) { + * var match = this.match(/^}/); + * if (match) { + * var parent = this.parent(); + * if (parent.type !== 'brace') { + * throw new Error('missing opening: ' + '}'); + * } + * + * utils.addClose(parent, Node); + * console.log(parent.nodes[parent.nodes.length - 1]): + * // { type: 'brace.close', val: '' }; + * + * // no need to return a node, since the parent + * // was already added to the AST + * return; + * } + * }); * ``` - * @param {String} `type` - * @return {Object} Returns a child node or undefined. + * @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 */ -Node.prototype.find = function(type) { - return utils.findNode(this.nodes, type); +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; }; /** - * Return true if the node is the given `type`. + * Wraps the given `node` with `*.open` and `*.close` nodes. * - * ```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} + * @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 */ -Node.prototype.isType = function(type) { - return utils.isType(this, type); +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; }; /** - * Return true if the `node.nodes` has the given `type`. + * Push the given `node` onto `parent.nodes`, and set `parent` as `node.parent. * * ```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 + * var parent = new Node({type: 'foo'}); + * var node = new Node({type: 'bar'}); + * utils.pushNode(parent, node); + * console.log(parent.nodes[0].type) // 'bar' + * console.log(node.parent.type) // 'foo' * ``` - * @param {String} `type` - * @return {Boolean} + * @param {Object} `parent` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Object} Returns the child node * @api public */ -Node.prototype.hasType = function(type) { - return utils.hasType(this, type); +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; }; /** - * Get the siblings array, or `null` if it doesn't exist. + * Unshift `node` onto `parent.nodes`, and set `parent` as `node.parent. * * ```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 + * 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' * ``` - * @return {Array} + * @param {Object} `parent` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {undefined} * @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; - } -}); +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); +}; /** - * Get the node's current index from `node.parent.nodes`. - * This should always be correct, even when the parent adds nodes. + * 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 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 + * 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 * ``` - * @return {Number} + * @param {Object} `parent` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. * @api public */ -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; +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(); +}; /** - * Get the previous node from the siblings array or `null`. + * 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 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' + * 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 * ``` - * @return {Object} + * @param {Object} `parent` + * @param {Object} `node` Instance of [snapdragon-node][] + * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. * @api public */ -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; +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(); +}; /** - * Get the siblings array, or `null` if it doesn't exist. + * Remove the specified `node` from `parent.nodes`. * * ```js + * var parent = new Node({type: 'abc'}); * 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 + * 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 * ``` - * @return {Object} + * @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 */ -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; - } +utils.removeNode = function(parent, node) { + assert(utils.isNode(parent), 'expected parent.node to be an instance of Node'); + assert(utils.isNode(node), 'expected node to be an instance of Node'); + + if (!parent.nodes) { return null; } -}); -/** - * 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 - */ + if (typeof parent.remove === 'function') { + return parent.remove(node); + } -Object.defineProperty(Node.prototype, 'first', { - get: function() { - return this.nodes ? this.nodes[0] : null; + var idx = parent.nodes.indexOf(node); + if (idx !== -1) { + return parent.nodes.splice(idx, 1); } -}); +}; /** - * Get the last node from `node.nodes`. + * Returns true if `node.type` matches the given `type`. Throws a + * `TypeError` if `node` is not an instance of `Node`. * * ```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' + * 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 * ``` - * @return {Object} The last node, or undefiend + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {String} `type` + * @return {Boolean} * @api public */ -Object.defineProperty(Node.prototype, 'last', { - get: function() { - return this.nodes ? utils.last(this.nodes) : null; +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'); + } } -}); +}; /** - * Get the last node from `node.nodes`. + * 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 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' + * 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 * ``` - * @return {Object} The last node, or undefiend + * @param {Object} `node` Instance of [snapdragon-node][] + * @param {String} `type` + * @return {Boolean} * @api public */ -Object.defineProperty(Node.prototype, 'scope', { - get: function() { - if (this.isScope !== true) { - return this.parent ? this.parent.scope : this; +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 this; - } -}); - -/** - * Get own property names from Node prototype, but only the - * first time `Node` is instantiated - */ - -function lazyKeys() { - if (!ownNames) { - ownNames = Object.getOwnPropertyNames(Node.prototype); } -} - -/** - * Simplified assertion. Throws an error is `val` is falsey. - */ - -function assert(val, message) { - if (!val) throw new Error(message); -} + return false; +}; /** - * Expose `Node` - */ - -exports = module.exports = Node; - - -/***/ }), -/* 546 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * define-property + * Returns the first node from `node.nodes` of the given `type` * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var isDescriptor = __webpack_require__(547); - -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 - }); -}; - - -/***/ }), -/* 547 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-descriptor + * ```js + * var node = new Node({ + * type: 'foo', + * nodes: [ + * new Node({type: 'text', val: 'abc'}), + * new Node({type: 'text', val: 'xyz'}) + * ] + * }); * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var typeOf = __webpack_require__(548); -var isAccessor = __webpack_require__(549); -var isData = __webpack_require__(551); - -module.exports = function isDescriptor(obj, key) { - if (typeOf(obj) !== 'object') { - return false; - } - if ('get' in obj) { - return isAccessor(obj, key); - } - return isData(obj, key); -}; - - -/***/ }), -/* 548 */ -/***/ (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'; - } - - // 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 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 isArguments(val) { - try { - if (typeof val.length === 'number' && typeof val.callee === 'function') { - return true; - } - } catch (err) { - if (err.message.indexOf('callee') !== -1) { - return true; +utils.firstOfType = function(nodes, type) { + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + if (utils.isType(node, type)) { + return node; } } - 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 + * 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 */ -function isBuffer(val) { - if (val.constructor && typeof val.constructor.isBuffer === 'function') { - return val.constructor.isBuffer(val); +utils.findNode = function(nodes, type) { + if (!Array.isArray(nodes)) { + return null; } - return false; -} - - -/***/ }), -/* 549 */ -/***/ (function(module, exports, __webpack_require__) { + if (typeof type === 'number') { + return nodes[type]; + } + return utils.firstOfType(nodes, type); +}; -"use strict"; -/*! - * is-accessor-descriptor +/** + * Returns true if the given node is an "*.open" node. * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. + * ```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 */ - - -var typeOf = __webpack_require__(550); - -// accessor descriptor properties -var accessor = { - get: 'function', - set: 'function', - configurable: 'boolean', - enumerable: 'boolean' +utils.isOpen = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + return node.type.slice(-5) === '.open'; }; -function isAccessorDescriptor(obj, prop) { - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; - } - - if (typeOf(obj) !== 'object') { - return false; - } - - if (has(obj, 'value') || has(obj, 'writable')) { - return false; - } - - if (!has(obj, 'get') || typeof obj.get !== 'function') { - return false; - } - - // tldr: it's valid to have "set" be undefined - // "set" might be undefined if `Object.getOwnPropertyDescriptor` - // was used to get the value, and only `get` was defined by the user - if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { - return false; - } +/** + * 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 + */ - for (var key in obj) { - if (!accessor.hasOwnProperty(key)) { - continue; - } +utils.isClose = function(node) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); + return node.type.slice(-6) === '.close'; +}; - if (typeOf(obj[key]) === accessor[key]) { - continue; - } +/** + * 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 + */ - if (typeof obj[key] !== 'undefined') { - return false; - } +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 true; -} - -function has(obj, key) { - return {}.hasOwnProperty.call(obj, key); -} + return false; +}; /** - * Expose `isAccessorDescriptor` + * 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 */ -module.exports = isAccessorDescriptor; - - -/***/ }), -/* 550 */ -/***/ (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'; +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; +}; - 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'; +/** + * 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 + */ - // Set, Map, WeakSet, WeakMap - case 'WeakMap': return 'weakmap'; - case 'WeakSet': return 'weakset'; - case 'Map': return 'map'; - case 'Set': return 'set'; +utils.hasOpenAndClose = function(node) { + return utils.hasOpen(node) && utils.hasClose(node); +}; - // 8-bit typed arrays - case 'Int8Array': return 'int8array'; - case 'Uint8Array': return 'uint8array'; - case 'Uint8ClampedArray': return 'uint8clampedarray'; +/** + * 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 + */ - // 16-bit typed arrays - case 'Int16Array': return 'int16array'; - case 'Uint16Array': return 'uint16array'; +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'); - // 32-bit typed arrays - case 'Int32Array': return 'int32array'; - case 'Uint32Array': return 'uint32array'; - case 'Float32Array': return 'float32array'; - case 'Float64Array': return 'float64array'; - } + var type = node.parent + ? node.parent.type + : node.type.replace(/\.open$/, ''); - if (isGeneratorObj(val)) { - return 'generator'; + if (!state.hasOwnProperty('inside')) { + state.inside = {}; } - - // Non-plain objects - type = toString.call(val); - switch (type) { - case '[object Object]': return 'object'; - // iterators - case '[object Map Iterator]': return 'mapiterator'; - case '[object Set Iterator]': return 'setiterator'; - case '[object String Iterator]': return 'stringiterator'; - case '[object Array Iterator]': return 'arrayiterator'; + if (!state.inside.hasOwnProperty(type)) { + state.inside[type] = []; } - // other - return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); + var arr = state.inside[type]; + arr.push(node); + return arr; }; -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; -} +/** + * 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 + */ -function isError(val) { - return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); -} +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'); -function isDate(val) { - if (val instanceof Date) return true; - return typeof val.toDateString === 'function' - && typeof val.getDate === 'function' - && typeof val.setDate === 'function'; -} + var type = node.parent + ? node.parent.type + : node.type.replace(/\.close$/, ''); -function isRegexp(val) { - if (val instanceof RegExp) return true; - return typeof val.flags === 'string' - && typeof val.ignoreCase === 'boolean' - && typeof val.multiline === 'boolean' - && typeof val.global === 'boolean'; -} + if (state.inside.hasOwnProperty(type)) { + return state.inside[type].pop(); + } +}; -function isGeneratorFn(name, val) { - return ctorName(name) === 'GeneratorFunction'; -} +/** + * 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 + */ -function isGeneratorObj(val) { - return typeof val.throw === 'function' - && typeof val.return === 'function' - && typeof val.next === 'function'; -} +utils.isEmpty = function(node, fn) { + assert(utils.isNode(node), 'expected node to be an instance of Node'); -function isArguments(val) { - try { - if (typeof val.length === 'number' && typeof val.callee === 'function') { + if (!Array.isArray(node.nodes)) { + if (node.type !== 'text') { return true; } - } catch (err) { - if (err.message.indexOf('callee') !== -1) { - return true; + if (typeof fn === 'function') { + return fn(node, node.parent); } + return !utils.trim(node.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); + 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 false; -} - -/***/ }), -/* 551 */ -/***/ (function(module, exports, __webpack_require__) { + return true; +}; -"use strict"; -/*! - * is-data-descriptor +/** + * Returns true if the `state.inside` stack for the given type exists + * and has one or more nodes on it. * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. + * ```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'); - -var typeOf = __webpack_require__(552); - -module.exports = function isDataDescriptor(obj, prop) { - // data descriptor properties - var data = { - configurable: 'boolean', - enumerable: 'boolean', - writable: 'boolean' - }; - - if (typeOf(obj) !== 'object') { + if (!state.hasOwnProperty('inside')) { return false; } - if (typeof prop === 'string') { - var val = Object.getOwnPropertyDescriptor(obj, prop); - return typeof val !== 'undefined'; + if (!state.inside.hasOwnProperty(type)) { + return false; } - if (!('value' in obj) && !('writable' in obj)) { + 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. + * + * ```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; } - for (var key in obj) { - if (key === 'value') continue; + var parent = node.parent; + if (typeof type === 'string') { + return (parent && parent.type === type) || utils.isInsideType(state, type); + } - if (!data.hasOwnProperty(key)) { - continue; + if (typeOf(type) === 'regexp') { + if (parent && parent.type && type.test(parent.type)) { + return true; } - if (typeOf(obj[key]) === data[key]) { - continue; - } + 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 (typeof obj[key] !== 'undefined') { - return false; + if (Array.isArray(val) && val.length !== 0 && type.test(key)) { + return true; + } } } - 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 + */ -/***/ }), -/* 552 */ -/***/ (function(module, exports) { - -var toString = Object.prototype.toString; +utils.last = function(arr, n) { + return arr[arr.length - (n || 1)]; +}; -module.exports = function kindOf(val) { - if (val === void 0) return 'undefined'; - if (val === null) return 'null'; +/** + * 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 + */ - 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'; +utils.arrayify = function(val) { + if (typeof val === 'string' && val !== '') { + return [val]; } - - 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 (!Array.isArray(val)) { + return []; } + return val; +}; - if (isGeneratorObj(val)) { - return 'generator'; - } +/** + * 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 + */ - // Non-plain objects - type = toString.call(val); - switch (type) { - case '[object Object]': return 'object'; - // iterators - case '[object Map Iterator]': return 'mapiterator'; - case '[object Set Iterator]': return 'setiterator'; - case '[object String Iterator]': return 'stringiterator'; - case '[object Array Iterator]': return 'arrayiterator'; - } +utils.stringify = function(val) { + return utils.arrayify(val).join(','); +}; - // other - return type.slice(8, -1).toLowerCase().replace(/\s/g, ''); +/** + * Ensure that the given value is a string and call `.trim()` on it, + * or return an empty string. + * + * @param {String} `str` + * @return {String} + * @api public + */ + +utils.trim = function(str) { + return typeof str === 'string' ? str.trim() : ''; }; -function ctorName(val) { - return typeof val.constructor === 'function' ? val.constructor.name : null; -} +/** + * Return true if val is an object + */ -function isArray(val) { - if (Array.isArray) return Array.isArray(val); - return val instanceof Array; +function isObject(val) { + return typeOf(val) === 'object'; } -function isError(val) { - return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'); -} +/** + * Return true if val is a string + */ -function isDate(val) { - if (val instanceof Date) return true; - return typeof val.toDateString === 'function' - && typeof val.getDate === 'function' - && typeof val.setDate === 'function'; +function isString(val) { + return typeof val === 'string'; } -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'; -} +/** + * Return true if val is a function + */ -function isGeneratorFn(name, val) { - return ctorName(name) === 'GeneratorFunction'; +function isFunction(val) { + return typeof val === 'function'; } -function isGeneratorObj(val) { - return typeof val.throw === 'function' - && typeof val.return === 'function' - && typeof val.next === 'function'; +/** + * Return true if val is an array + */ + +function isArray(val) { + return Array.isArray(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; - } +/** + * 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 false; + return compiler.append(val, node); } /** - * If you need to support Safari 5-7 (8-10 yr-old browser), - * take a look at https://github.com/feross/is-buffer + * Simplified assertion. Throws an error is `val` is falsey. */ -function isBuffer(val) { - if (val.constructor && typeof val.constructor.isBuffer === 'function') { - return val.constructor.isBuffer(val); - } - return false; +function assert(val, message) { + if (!val) throw new Error(message); } /***/ }), -/* 553 */ +/* 568 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(540); -var utils = module.exports; +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); /** - * Returns true if the given value is a node. - * - * ```js - * var Node = require('snapdragon-node'); - * var node = new Node({type: 'foo'}); - * console.log(utils.isNode(node)); //=> true - * console.log(utils.isNode({})); //=> false - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @returns {Boolean} - * @api public + * Customize Snapdragon parser and renderer */ -utils.isNode = function(node) { - return typeOf(node) === 'object' && node.isNode === true; -}; +function Braces(options) { + this.options = extend({}, options); +} /** - * Emit an empty string for the given `node`. - * - * ```js - * // do nothing for beginning-of-string - * snapdragon.compiler.set('bos', utils.noop); - * ``` - * @param {Object} `node` Instance of [snapdragon-node][] - * @returns {undefined} - * @api public + * Initialize braces */ -utils.noop = function(node) { - append(this, '', node); -}; +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; -/** - * 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 - */ + compilers(this.snapdragon, opts); + parsers(this.snapdragon, opts); -utils.identity = function(node) { - append(this, node.val, node); + /** + * 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; + }); }; /** - * 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 + * Decorate `.parse` method */ -utils.append = function(val) { - return function(node) { - append(this, val, node); - }; +Braces.prototype.parse = function(ast, options) { + if (ast && typeof ast === 'object' && ast.nodes) return ast; + this.init(options); + return this.snapdragon.parse(ast, options); }; /** - * 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 + * Decorate `.compile` method */ -utils.toNoop = function(node, nodes) { - if (nodes) { - node.nodes = nodes; +Braces.prototype.compile = function(ast, options) { + if (typeof ast === 'string') { + ast = this.parse(ast, options); } else { - delete node.nodes; - node.type = 'text'; - node.val = ''; + this.init(options); } + return this.snapdragon.compile(ast, options); }; /** - * 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 + * Expand */ -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; +Braces.prototype.expand = function(pattern) { + var ast = this.parse(pattern, {expand: true}); + return this.compile(ast, {expand: true}); }; /** - * 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 + * Optimize */ -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; +Braces.prototype.optimize = function(pattern) { + var ast = this.parse(pattern, {optimize: true}); + return this.compile(ast, {optimize: true}); }; /** - * 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 + * Expose `Braces` */ -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 = ''; - } +module.exports = Braces; - 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; -}; -/** - * 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 - */ +/***/ }), +/* 569 */ +/***/ (function(module, exports, __webpack_require__) { -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'); +"use strict"; - 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; -}; +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 = {}; /** - * Wraps the given `node` with `*.open` and `*.close` nodes. + * Create a new instance of `Snapdragon` with the given `options`. * - * @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 snapdragon = new Snapdragon(); + * ``` + * + * @param {Object} `options` * @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'); +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); - utils.addOpen(node, Node, filter); - utils.addClose(node, Node, filter); - return node; -}; + 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; + } + }); +} /** - * Push the given `node` onto `parent.nodes`, and set `parent` as `node.parent. + * 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 - * 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' + * 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 {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Object} Returns the child node + * @param {String} `type` + * @param {RegExp|Function} `regex` + * @return {Object} Returns the parser instance for chaining * @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; +Snapdragon.prototype.capture = function() { + return this.parser.capture.apply(this.parser, arguments); }; /** - * Unshift `node` onto `parent.nodes`, and set `parent` as `node.parent. + * Register a plugin `fn`. * * ```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 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} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {undefined} + * @param {Object} `fn` * @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); +Snapdragon.prototype.use = function(fn) { + fn.call(this, this); + return this; }; /** - * 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`. + * Parse the given `str`. * * ```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 snapdragon = new Snapdgragon([options]); + * // register parsers + * snapdragon.parser.use(function() {}); + * + * // parse + * var ast = snapdragon.parse('foo/bar'); + * console.log(ast); * ``` - * @param {Object} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. + * @param {String} `str` + * @param {Object} `options` Set `options.sourcemap` to true to enable source maps. + * @return {Object} Returns an AST. * @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(); +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; }; /** - * 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`. + * Compile the given `AST`. * * ```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 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} `parent` - * @param {Object} `node` Instance of [snapdragon-node][] - * @return {Number|Undefined} Returns the length of `node.nodes` or undefined. + * @param {Object} `ast` + * @param {Object} `options` + * @return {Object} Returns an object with an `output` property with the rendered string. * @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(); +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; }; /** - * 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 + * Expose `Snapdragon` */ -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'); +module.exports = Snapdragon; - if (!parent.nodes) { - return null; - } +/** + * Expose `Parser` and `Compiler` + */ - if (typeof parent.remove === 'function') { - return parent.remove(node); - } +module.exports.Compiler = Compiler; +module.exports.Parser = Parser; - var idx = parent.nodes.indexOf(node); - if (idx !== -1) { - return parent.nodes.splice(idx, 1); - } -}; + +/***/ }), +/* 570 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +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); /** - * 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 + * Optionally define a custom `cache` namespace to use. */ -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'); +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; } - } -}; + }); -/** - * 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 - */ + /** + * 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 + */ -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; -}; + define(Base, 'use', function(fn) { + fns.push(fn); + return Base; + }); -/** - * Returns the first node from `node.nodes` of the given `type` - * - * ```js - * var node = new Node({ - * type: 'foo', - * nodes: [ - * new Node({type: 'text', val: 'abc'}), - * new Node({type: 'text', val: 'xyz'}) - * ] - * }); - * - * var textNode = utils.firstOfType(node.nodes, 'text'); - * console.log(textNode.val); - * //=> 'abc' - * ``` - * @param {Array} `nodes` - * @param {String} `type` - * @return {Object|undefined} Returns the first matching node or undefined. - * @api public - */ + /** + * 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. + */ -utils.firstOfType = function(nodes, type) { - for (var i = 0; i < nodes.length; i++) { - var node = nodes[i]; - if (utils.isType(node, type)) { - return node; + define(Base, 'run', function(obj, prop, arr) { + var len = arr.length, i = 0; + while (len--) { + obj[prop](arr[i++]); } - } -}; + return Base; + }); -/** - * 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 - */ + /** + * 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 + */ -utils.findNode = function(nodes, type) { - if (!Array.isArray(nodes)) { - return null; - } - if (typeof type === 'number') { - return nodes[type]; - } - return utils.firstOfType(nodes, type); -}; + define(Base, 'extend', cu.extend(Base, function(Ctor, Parent) { + Ctor.prototype.mixins = Ctor.prototype.mixins || []; -/** - * 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 - */ + define(Ctor, 'mixin', function(fn) { + var mixin = fn(Ctor.prototype, Ctor); + if (typeof mixin === 'function') { + Ctor.prototype.mixins.push(mixin); + } + return Ctor; + }); -utils.isOpen = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - return node.type.slice(-5) === '.open'; -}; + define(Ctor, 'mixins', function(Child) { + Base.run(Child, 'mixin', Ctor.prototype.mixins); + return Ctor; + }); -/** - * 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 - */ + Ctor.prototype.mixin = function(key, value) { + Ctor.prototype[key] = value; + return this; + }; + return Base; + })); -utils.isClose = function(node) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); - return node.type.slice(-6) === '.close'; -}; + /** + * 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 + */ -/** - * 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 - */ + define(Base, 'mixin', function(fn) { + var mixin = fn(Base.prototype, Base); + if (typeof mixin === 'function') { + Base.prototype.mixins.push(mixin); + } + return Base; + }); -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; -}; + /** + * 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 + */ -/** - * 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 - */ + define(Base, 'mixins', function(Child) { + Base.run(Child, 'mixin', Base.prototype.mixins); + return Base; + }); -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; -}; + /** + * Similar to `util.inherit`, but copies all static properties, prototype properties, and + * getters/setters from `Provider` to `Receiver`. See [class-utils][]{#inherit} for more details. + * + * ```js + * Base.inherit(Foo, Bar); + * ``` + * @name #inherit + * @param {Function} `Receiver` Receiving (child) constructor + * @param {Function} `Provider` Providing (parent) constructor + * @return {Object} Returns the `Base` constructor for chaining + * @api public + */ + + define(Base, 'inherit', cu.inherit); + define(Base, 'bubble', cu.bubble); + return Base; +} /** - * 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 + * Expose `Base` with default settings */ -utils.hasOpenAndClose = function(node) { - return utils.hasOpen(node) && utils.hasClose(node); -}; +module.exports = namespace(); /** - * 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 + * Allow users to define a namespace */ -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$/, ''); +module.exports.namespace = namespace; - if (!state.hasOwnProperty('inside')) { - state.inside = {}; - } - if (!state.inside.hasOwnProperty(type)) { - state.inside[type] = []; - } - var arr = state.inside[type]; - arr.push(node); - return arr; -}; +/***/ }), +/* 571 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * 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`. +"use strict"; +/*! + * define-property * - * ```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 + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -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 - */ +var isDescriptor = __webpack_require__(535); -utils.isEmpty = function(node, fn) { - assert(utils.isNode(node), 'expected node to be an instance of Node'); +module.exports = function defineProperty(obj, prop, val) { + if (typeof obj !== 'object' && typeof obj !== 'function') { + throw new TypeError('expected an object or function.'); + } - if (!Array.isArray(node.nodes)) { - if (node.type !== 'text') { - return true; - } - if (typeof fn === 'function') { - return fn(node, node.parent); - } - return !utils.trim(node.val); + if (typeof prop !== 'string') { + throw new TypeError('expected `prop` to be a string.'); } - for (var i = 0; i < node.nodes.length; i++) { - var child = node.nodes[i]; - if (utils.isOpen(child) || utils.isClose(child)) { - continue; - } - if (!utils.isEmpty(child, fn)) { - return false; - } + if (isDescriptor(val) && ('set' in val || 'get' in val)) { + return Object.defineProperty(obj, prop, val); } - return true; + return Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: val + }); }; -/** - * 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'); +/***/ }), +/* 572 */ +/***/ (function(module, exports, __webpack_require__) { - if (!state.hasOwnProperty('inside')) { - return false; - } +"use strict"; - if (!state.inside.hasOwnProperty(type)) { - return false; - } - return state.inside[type].length > 0; -}; +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); /** - * Returns true if `node` is either a child or grand-child of the given `type`, - * or `state.inside[type]` is a non-empty array. + * Create a `Cache` constructor that when instantiated will + * store values on the given `prop`. * * ```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 + * var Cache = require('cache-base').namespace('data'); + * var cache = new Cache(); + * + * cache.set('foo', 'bar'); + * //=> {data: {foo: 'bar'}} * ``` - * @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} + * @param {String} `prop` The property name to use for storing values. + * @return {Function} Returns a custom `Cache` constructor * @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'); +function namespace(prop) { - if (Array.isArray(type)) { - for (var i = 0; i < type.length; i++) { - if (utils.isInside(state, node, type[i])) { - return true; - } + /** + * Create a new `Cache`. Internally the `Cache` constructor is created using + * the `namespace` function, with `cache` defined as the storage object. + * + * ```js + * var app = new Cache(); + * ``` + * @param {Object} `cache` Optionally pass an object to initialize with. + * @constructor + * @api public + */ + + function Cache(cache) { + if (prop) { + this[prop] = {}; + } + if (cache) { + this.set(cache); } - return false; } - var parent = node.parent; - if (typeof type === 'string') { - return (parent && parent.type === type) || utils.isInsideType(state, type); - } + /** + * Inherit Emitter + */ - if (typeOf(type) === 'regexp') { - if (parent && parent.type && type.test(parent.type)) { - return true; + Emitter(Cache.prototype); + + /** + * Assign `value` to `key`. Also emits `set` with + * the key and value. + * + * ```js + * app.on('set', function(key, val) { + * // do something when `set` is emitted + * }); + * + * app.set(key, value); + * + * // also takes an object or array + * app.set({name: 'Halle'}); + * app.set([{foo: 'bar'}, {baz: 'quux'}]); + * console.log(app); + * //=> {name: 'Halle', foo: 'bar', baz: 'quux'} + * ``` + * + * @name .set + * @emits `set` with `key` and `value` as arguments. + * @param {String} `key` + * @param {any} `value` + * @return {Object} Returns the instance for chaining. + * @api public + */ + + Cache.prototype.set = function(key, val) { + if (Array.isArray(key) && arguments.length === 2) { + key = toPath(key); + } + if (isObject(key) || Array.isArray(key)) { + this.visit('set', key); + } else { + set(prop ? this[prop] : this, key, val); + this.emit('set', key, val); } + return this; + }; - 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]; + /** + * 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 + */ - if (Array.isArray(val) && val.length !== 0 && type.test(key)) { - return true; - } + Cache.prototype.union = function(key, val) { + if (Array.isArray(key) && arguments.length === 2) { + key = toPath(key); } - } - return false; -}; + var ctx = prop ? this[prop] : this; + union(ctx, key, arrayify(val)); + this.emit('union', val); + return this; + }; -/** - * 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 - */ + /** + * 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.last = function(arr, n) { - return arr[arr.length - (n || 1)]; -}; + Cache.prototype.get = function(key) { + key = toPath(arguments); -/** - * 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 - */ + var ctx = prop ? this[prop] : this; + var val = get(ctx, key); -utils.arrayify = function(val) { - if (typeof val === 'string' && val !== '') { - return [val]; - } - if (!Array.isArray(val)) { - return []; - } - return val; -}; + this.emit('get', key, val); + 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 - */ + /** + * 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.stringify = function(val) { - return utils.arrayify(val).join(','); -}; + Cache.prototype.has = function(key) { + key = toPath(arguments); -/** - * 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 - */ + var ctx = prop ? this[prop] : this; + var val = get(ctx, key); -utils.trim = function(str) { - return typeof str === 'string' ? str.trim() : ''; -}; + var has = typeof val !== 'undefined'; + this.emit('has', key, has); + return has; + }; -/** - * Return true if val is an object - */ + /** + * 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 + */ -function isObject(val) { - return typeOf(val) === 'object'; -} + 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; + }; -/** - * Return true if val is a string - */ + /** + * Reset the entire cache to an empty object. + * + * ```js + * app.clear(); + * ``` + * @api public + */ -function isString(val) { - return typeof val === 'string'; -} + Cache.prototype.clear = function() { + if (prop) { + this[prop] = {}; + } + }; -/** - * Return true if val is a function - */ + /** + * 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 + */ -function isFunction(val) { - return typeof val === 'function'; + Cache.prototype.visit = function(method, val) { + visit(this, method, val); + return this; + }; + + return Cache; } /** - * Return true if val is an array + * Cast val to an array */ -function isArray(val) { - return Array.isArray(val); +function arrayify(val) { + return val ? (Array.isArray(val) ? val : [val]) : []; } /** - * Shim to ensure the `.append` methods work with any version of snapdragon + * Expose `Cache` */ -function append(compiler, val, node) { - if (typeof compiler.append !== 'function') { - return compiler.emit(val, node); - } - return compiler.append(val, node); -} +module.exports = namespace(); /** - * Simplified assertion. Throws an error is `val` is falsey. + * Expose `Cache.namespace` */ -function assert(val, message) { - if (!val) throw new Error(message); -} +module.exports.namespace = namespace; /***/ }), -/* 554 */ +/* 573 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; - - -var extend = __webpack_require__(525); -var Snapdragon = __webpack_require__(555); -var compilers = __webpack_require__(529); -var parsers = __webpack_require__(544); -var utils = __webpack_require__(530); + +/** + * 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; +}; -/** - * Customize Snapdragon parser and renderer - */ -function Braces(options) { - this.options = extend({}, options); -} +/***/ }), +/* 574 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Initialize braces +"use strict"; +/*! + * collection-visit + * + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -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); -}; +var visit = __webpack_require__(575); +var mapVisit = __webpack_require__(576); -/** - * Decorate `.compile` method - */ +module.exports = function(collection, method, val) { + var result; -Braces.prototype.compile = function(ast, options) { - if (typeof ast === 'string') { - ast = this.parse(ast, options); + 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 { - this.init(options); + result = visit.apply(null, arguments); } - 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 - */ + if (typeof result !== 'undefined') { + return result; + } -Braces.prototype.optimize = function(pattern) { - var ast = this.parse(pattern, {optimize: true}); - return this.compile(ast, {optimize: true}); + return collection; }; -/** - * Expose `Braces` - */ - -module.exports = Braces; - /***/ }), -/* 555 */ +/* 575 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - - -var Base = __webpack_require__(556); -var define = __webpack_require__(517); -var Compiler = __webpack_require__(585); -var Parser = __webpack_require__(614); -var utils = __webpack_require__(594); -var regexCache = {}; -var cache = {}; - -/** - * Create a new instance of `Snapdragon` with the given `options`. - * - * ```js - * var snapdragon = new Snapdragon(); - * ``` +/*! + * object-visit * - * @param {Object} `options` - * @api public + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -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; - } - }); +var isObject = __webpack_require__(534); - Object.defineProperty(this, 'regex', { - get: function() { - return this.parser.regex; - } - }); -} +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.'); + } -/** - * Inherit Base - */ + if (typeof method !== 'string') { + throw new Error('object-visit expects `method` name to be a string'); + } -Base.extend(Snapdragon); + if (typeof thisArg[method] !== 'function') { + return thisArg; + } -/** - * 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 - */ + var args = [].slice.call(arguments, 3); + target = target || {}; -Snapdragon.prototype.capture = function() { - return this.parser.capture.apply(this.parser, arguments); + for (var key in target) { + var arr = [key, target[key]].concat(args); + thisArg[method].apply(thisArg, arr); + } + return thisArg; }; -/** - * 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; -}; +/***/ }), +/* 576 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * 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 - */ +"use strict"; -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; -}; +var util = __webpack_require__(112); +var visit = __webpack_require__(575); /** - * 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'); + * Map `visit` over an array of objects. * - * // 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 + * @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. */ -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; -}; +module.exports = function mapVisit(collection, method, val) { + if (isObject(val)) { + return visit.apply(null, arguments); + } -/** - * Expose `Snapdragon` - */ + if (!Array.isArray(val)) { + throw new TypeError('expected an array: ' + util.inspect(val)); + } -module.exports = Snapdragon; + var args = [].slice.call(arguments, 3); -/** - * Expose `Parser` and `Compiler` - */ + 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)); + } + } +}; -module.exports.Compiler = Compiler; -module.exports.Parser = Parser; +function isObject(val) { + return val && (typeof val === 'function' || (!Array.isArray(val) && typeof val === 'object')); +} /***/ }), -/* 556 */ +/* 577 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - - -var util = __webpack_require__(111); -var define = __webpack_require__(557); -var CacheBase = __webpack_require__(558); -var Emitter = __webpack_require__(559); -var isObject = __webpack_require__(535); -var merge = __webpack_require__(576); -var pascal = __webpack_require__(579); -var cu = __webpack_require__(580); - -/** - * Optionally define a custom `cache` namespace to use. +/*! + * to-object-path + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. */ -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 - */ +var typeOf = __webpack_require__(559); - Base.prototype.use = function(fn) { - fn.call(this, this); - return this; - }; +module.exports = function toPath(args) { + if (typeOf(args) !== 'arguments') { + args = arguments; + } + return filter(args).join('.'); +}; - /** - * 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 - */ +function filter(arr) { + var len = arr.length; + var idx = -1; + var res = []; - Base.prototype.define = function(key, val) { - if (isObject(key)) { - return this.visit('define', key); + 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); } - define(this, key, val); - return this; - }; + } + return res; +} - /** - * 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; - }; +/***/ }), +/* 578 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * Non-enumberable mixin array, used by the static [Base.mixin]() method. - */ +"use strict"; - 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 - */ +var isObject = __webpack_require__(550); +var union = __webpack_require__(579); +var get = __webpack_require__(580); +var set = __webpack_require__(581); - Object.defineProperty(Base.prototype, 'base', { - configurable: true, - get: function() { - return this.parent ? this.parent.base : this; - } - }); +module.exports = function unionValue(obj, prop, value) { + if (!isObject(obj)) { + throw new TypeError('union-value expects the first argument to be an object.'); + } - /** - * 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 - */ + if (typeof prop !== 'string') { + throw new TypeError('union-value expects `prop` to be a string.'); + } - define(Base, 'use', function(fn) { - fns.push(fn); - return Base; - }); + var arr = arrayify(get(obj, prop)); + set(obj, prop, union(arr, arrayify(value))); + return obj; +}; - /** - * 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. - */ +function arrayify(val) { + if (val === null || typeof val === 'undefined') { + return []; + } + if (Array.isArray(val)) { + return val; + } + return [val]; +} - 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 - */ +/***/ }), +/* 579 */ +/***/ (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; - }); +module.exports = function union(init) { + if (!Array.isArray(init)) { + throw new TypeError('arr-union expects the first argument to be an array.'); + } - Ctor.prototype.mixin = function(key, value) { - Ctor.prototype[key] = value; - return this; - }; - return Base; - })); + var len = arguments.length; + var i = 0; - /** - * 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 - */ + while (++i < len) { + var arg = arguments[i]; + if (!arg) continue; - define(Base, 'mixin', function(fn) { - var mixin = fn(Base.prototype, Base); - if (typeof mixin === 'function') { - Base.prototype.mixins.push(mixin); + if (!Array.isArray(arg)) { + arg = [arg]; } - 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 - */ + for (var j = 0; j < arg.length; j++) { + var ele = arg[j]; - define(Base, 'mixins', function(Child) { - Base.run(Child, 'mixin', Base.prototype.mixins); - return Base; - }); + if (init.indexOf(ele) >= 0) { + continue; + } + init.push(ele); + } + } + return init; +}; - /** - * Similar to `util.inherit`, but copies all static properties, prototype properties, and - * getters/setters from `Provider` to `Receiver`. See [class-utils][]{#inherit} for more details. - * - * ```js - * Base.inherit(Foo, Bar); - * ``` - * @name #inherit - * @param {Function} `Receiver` Receiving (child) constructor - * @param {Function} `Provider` Providing (parent) constructor - * @return {Object} Returns the `Base` constructor for chaining - * @api public - */ - define(Base, 'inherit', cu.inherit); - define(Base, 'bubble', cu.bubble); - return Base; -} +/***/ }), +/* 580 */ +/***/ (function(module, exports) { -/** - * Expose `Base` with default settings +/*! + * get-value + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. */ -module.exports = namespace(); +module.exports = function(obj, prop, a, b, c) { + if (!isObject(obj) || !prop) { + return obj; + } -/** - * Allow users to define a namespace - */ + prop = toString(prop); -module.exports.namespace = namespace; + // allowing for multiple properties to be passed as + // a string or array, but much faster (3-4x) than doing + // `[].slice.call(arguments)` + if (a) prop += '.' + toString(a); + if (b) prop += '.' + toString(b); + if (c) prop += '.' + toString(c); + + if (prop in obj) { + return obj[prop]; + } + + var segs = prop.split('.'); + var len = segs.length; + var i = -1; + + while (obj && (++i < len)) { + var key = segs[i]; + while (key[key.length - 1] === '\\') { + key = key.slice(0, -1) + '.' + segs[++i]; + } + obj = obj[key]; + } + return obj; +}; + +function isObject(val) { + return val !== null && (typeof val === 'object' || typeof val === 'function'); +} + +function toString(val) { + if (!val) return ''; + if (Array.isArray(val)) { + return val.join('.'); + } + return val; +} /***/ }), -/* 557 */ +/* 581 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * define-property + * set-value * - * Copyright (c) 2015, 2017, Jon Schlinkert. + * Copyright (c) 2014-2015, 2017, Jon Schlinkert. * Released under the MIT License. */ -var isDescriptor = __webpack_require__(547); +var split = __webpack_require__(553); +var extend = __webpack_require__(549); +var isPlainObject = __webpack_require__(543); +var isObject = __webpack_require__(550); -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(obj, prop, val) { + if (!isObject(obj)) { + return obj; + } + + if (Array.isArray(prop)) { + prop = [].concat.apply([], prop).join('.'); } if (typeof prop !== 'string') { - throw new TypeError('expected `prop` to be a string.'); + return obj; } - if (isDescriptor(val) && ('set' in val || 'get' in val)) { - return Object.defineProperty(obj, prop, val); + 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; + } } - return Object.defineProperty(obj, prop, { - configurable: true, - enumerable: false, - writable: true, - value: val - }); + return obj; }; +function isValidKey(key) { + return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; +} + /***/ }), -/* 558 */ +/* 582 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; - - -var isObject = __webpack_require__(535); -var Emitter = __webpack_require__(559); -var visit = __webpack_require__(560); -var toPath = __webpack_require__(563); -var union = __webpack_require__(564); -var del = __webpack_require__(568); -var get = __webpack_require__(566); -var has = __webpack_require__(573); -var set = __webpack_require__(567); - -/** - * Create a `Cache` constructor that when instantiated will - * store values on the given `prop`. - * - * ```js - * var Cache = require('cache-base').namespace('data'); - * var cache = new Cache(); +/*! + * unset-value * - * 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 + * Copyright (c) 2015, 2017, Jon Schlinkert. + * Released under the MIT License. */ -function namespace(prop) { - /** - * Create a new `Cache`. Internally the `Cache` constructor is created using - * the `namespace` function, with `cache` defined as the storage object. - * - * ```js - * var app = new Cache(); - * ``` - * @param {Object} `cache` Optionally pass an object to initialize with. - * @constructor - * @api public - */ - function Cache(cache) { - if (prop) { - this[prop] = {}; - } - if (cache) { - this.set(cache); - } +var isObject = __webpack_require__(534); +var has = __webpack_require__(583); + +module.exports = function unset(obj, prop) { + if (!isObject(obj)) { + throw new TypeError('expected an object.'); + } + if (obj.hasOwnProperty(prop)) { + delete obj[prop]; + return true; } - /** - * Inherit Emitter - */ + 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; +}; - 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 - */ +/***/ }), +/* 583 */ +/***/ (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"; +/*! + * has-value + * + * Copyright (c) 2014-2016, Jon Schlinkert. + * Licensed under the MIT License. + */ - /** - * Union `array` to `key`. Also emits `set` with - * the key and value. - * - * ```js - * app.union('a.b', ['foo']); - * app.union('a.b', ['bar']); - * console.log(app.get('a')); - * //=> {b: ['foo', 'bar']} - * ``` - * @name .union - * @param {String} `key` - * @param {any} `value` - * @return {Object} Returns the instance for chaining. - * @api public - */ - Cache.prototype.union = function(key, val) { - if (Array.isArray(key) && arguments.length === 2) { - key = toPath(key); - } - var ctx = prop ? this[prop] : this; - union(ctx, key, arrayify(val)); - this.emit('union', val); - return this; - }; - /** - * Return the value of `key`. Dot notation may be used - * to get [nested property values][get-value]. - * - * ```js - * app.set('a.b.c', 'd'); - * app.get('a.b'); - * //=> {c: 'd'} - * - * app.get(['a', 'b']); - * //=> {c: 'd'} - * ``` - * - * @name .get - * @emits `get` with `key` and `value` as arguments. - * @param {String} `key` The name of the property to get. Dot-notation may be used. - * @return {any} Returns the value of `key` - * @api public - */ +var isObject = __webpack_require__(584); +var hasValues = __webpack_require__(586); +var get = __webpack_require__(580); - Cache.prototype.get = function(key) { - key = toPath(arguments); +module.exports = function(obj, prop, noZero) { + if (isObject(obj)) { + return hasValues(get(obj, prop), noZero); + } + return hasValues(obj, prop); +}; - var ctx = prop ? this[prop] : this; - var val = get(ctx, key); - this.emit('get', key, val); - return val; - }; +/***/ }), +/* 584 */ +/***/ (function(module, exports, __webpack_require__) { - /** - * 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 - */ +"use strict"; +/*! + * isobject + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ - Cache.prototype.has = function(key) { - key = toPath(arguments); - var ctx = prop ? this[prop] : this; - var val = get(ctx, key); - var has = typeof val !== 'undefined'; - this.emit('has', key, has); - return has; - }; +var isArray = __webpack_require__(585); - /** - * 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 - */ +module.exports = function isObject(val) { + return val != null && typeof val === 'object' && isArray(val) === false; +}; - Cache.prototype.del = function(key) { - if (Array.isArray(key)) { - this.visit('del', key); - } else { - del(prop ? this[prop] : this, key); - this.emit('del', key); - } - return this; - }; - /** - * Reset the entire cache to an empty object. - * - * ```js - * app.clear(); - * ``` - * @api public - */ +/***/ }), +/* 585 */ +/***/ (function(module, exports) { - Cache.prototype.clear = function() { - if (prop) { - this[prop] = {}; - } - }; +var toString = {}.toString; - /** - * Visit `method` over the properties in the given object, or map - * visit over the object-elements in an array. - * - * @name .visit - * @param {String} `method` The name of the `base` method to call. - * @param {Object|Array} `val` The object or array to iterate over. - * @return {Object} Returns the instance for chaining. - * @api public - */ +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; - Cache.prototype.visit = function(method, val) { - visit(this, method, val); - return this; - }; - return Cache; -} +/***/ }), +/* 586 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Cast val to an array +"use strict"; +/*! + * has-values + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. */ -function arrayify(val) { - return val ? (Array.isArray(val) ? val : [val]) : []; -} -/** - * Expose `Cache` - */ -module.exports = namespace(); +module.exports = function hasValue(o, noZero) { + if (o === null || o === undefined) { + return false; + } -/** - * Expose `Cache.namespace` - */ + if (typeof o === 'boolean') { + return true; + } -module.exports.namespace = namespace; + if (typeof o === 'number') { + if (o === 0 && noZero === true) { + return false; + } + return true; + } + + if (o.length !== undefined) { + return o.length !== 0; + } + + for (var key in o) { + if (o.hasOwnProperty(key)) { + return true; + } + } + return false; +}; /***/ }), -/* 559 */ +/* 587 */ /***/ (function(module, exports, __webpack_require__) { - -/** - * Expose `Emitter`. - */ - -if (true) { - module.exports = Emitter; -} - -/** - * Initialize a new `Emitter`. - * - * @api public - */ - -function Emitter(obj) { - if (obj) return mixin(obj); -}; - -/** - * Mixin the emitter properties. - * - * @param {Object} obj - * @return {Object} - * @api private - */ - -function mixin(obj) { - for (var key in Emitter.prototype) { - obj[key] = Emitter.prototype[key]; - } - return obj; -} - -/** - * Listen on the given `event` with `fn`. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.on = -Emitter.prototype.addEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - (this._callbacks['$' + event] = this._callbacks['$' + event] || []) - .push(fn); - return this; -}; - -/** - * Adds an `event` listener that will be invoked a single - * time then automatically removed. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.once = function(event, fn){ - function on() { - this.off(event, on); - fn.apply(this, arguments); - } - - on.fn = fn; - this.on(event, on); - return this; -}; - -/** - * Remove the given callback for `event` or all - * registered callbacks. - * - * @param {String} event - * @param {Function} fn - * @return {Emitter} - * @api public - */ - -Emitter.prototype.off = -Emitter.prototype.removeListener = -Emitter.prototype.removeAllListeners = -Emitter.prototype.removeEventListener = function(event, fn){ - this._callbacks = this._callbacks || {}; - - // all - if (0 == arguments.length) { - this._callbacks = {}; - return this; - } - - // specific event - var callbacks = this._callbacks['$' + event]; - if (!callbacks) return this; - - // remove all handlers - if (1 == arguments.length) { - delete this._callbacks['$' + event]; - return this; - } - - // remove specific handler - var cb; - for (var i = 0; i < callbacks.length; i++) { - cb = callbacks[i]; - if (cb === fn || cb.fn === fn) { - callbacks.splice(i, 1); - break; - } - } - return this; -}; - -/** - * Emit `event` with the given args. - * - * @param {String} event - * @param {Mixed} ... - * @return {Emitter} - */ - -Emitter.prototype.emit = function(event){ - this._callbacks = this._callbacks || {}; - var args = [].slice.call(arguments, 1) - , callbacks = this._callbacks['$' + event]; - - if (callbacks) { - callbacks = callbacks.slice(0); - for (var i = 0, len = callbacks.length; i < len; ++i) { - callbacks[i].apply(this, args); - } - } - - return this; -}; - -/** - * Return array of callbacks for `event`. - * - * @param {String} event - * @return {Array} - * @api public - */ - -Emitter.prototype.listeners = function(event){ - this._callbacks = this._callbacks || {}; - return this._callbacks['$' + event] || []; -}; - -/** - * Check if this emitter has `event` handlers. - * - * @param {String} event - * @return {Boolean} - * @api public - */ - -Emitter.prototype.hasListeners = function(event){ - return !! this.listeners(event).length; -}; +"use strict"; +/*! + * has-value + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Licensed under the MIT License. + */ + + + +var isObject = __webpack_require__(534); +var hasValues = __webpack_require__(588); +var get = __webpack_require__(580); + +module.exports = function(val, prop) { + return hasValues(isObject(val) && prop ? get(val, prop) : val); +}; /***/ }), -/* 560 */ +/* 588 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * collection-visit + * has-values * - * Copyright (c) 2015, 2017, Jon Schlinkert. + * Copyright (c) 2014-2015, 2017, Jon Schlinkert. * Released under the MIT License. */ -var visit = __webpack_require__(561); -var mapVisit = __webpack_require__(562); +var typeOf = __webpack_require__(589); +var isNumber = __webpack_require__(558); -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); +module.exports = function hasValue(val) { + // is-number checks for NaN and other edge cases + if (isNumber(val)) { + return true; } - if (typeof result !== 'undefined') { - return result; + 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 collection; }; /***/ }), -/* 561 */ +/* 589 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -/*! - * object-visit +var isBuffer = __webpack_require__(560); +var toString = Object.prototype.toString; + +/** + * Get the native `typeof` a value. * - * Copyright (c) 2015, 2017, Jon Schlinkert. - * Released under the MIT License. + * @param {*} `val` + * @return {*} Native javascript type */ +module.exports = function kindOf(val) { + // primitivies + if (typeof val === 'undefined') { + return 'undefined'; + } + if (val === null) { + return 'null'; + } + if (val === true || val === false || val instanceof Boolean) { + return 'boolean'; + } + if (typeof val === 'string' || val instanceof String) { + return 'string'; + } + if (typeof val === 'number' || val instanceof Number) { + return 'number'; + } + // functions + if (typeof val === 'function' || val instanceof Function) { + return 'function'; + } -var isObject = __webpack_require__(535); + // array + if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { + return 'array'; + } -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.'); + // check for instances of RegExp and Date before calling `toString` + if (val instanceof RegExp) { + return 'regexp'; + } + if (val instanceof Date) { + return 'date'; } - if (typeof method !== 'string') { - throw new Error('object-visit expects `method` name to be a string'); + // other objects + var type = toString.call(val); + + if (type === '[object RegExp]') { + return 'regexp'; + } + if (type === '[object Date]') { + return 'date'; + } + if (type === '[object Arguments]') { + return 'arguments'; + } + if (type === '[object Error]') { + return 'error'; + } + if (type === '[object Promise]') { + return 'promise'; } - if (typeof thisArg[method] !== 'function') { - return thisArg; + // buffer + if (isBuffer(val)) { + return 'buffer'; + } + + // es6: Map, WeakMap, Set, WeakSet + if (type === '[object Set]') { + return 'set'; + } + if (type === '[object WeakSet]') { + return 'weakset'; + } + if (type === '[object Map]') { + return 'map'; + } + if (type === '[object WeakMap]') { + return 'weakmap'; + } + if (type === '[object Symbol]') { + return 'symbol'; + } + + // typed arrays + if (type === '[object Int8Array]') { + return 'int8array'; + } + if (type === '[object Uint8Array]') { + return 'uint8array'; + } + if (type === '[object Uint8ClampedArray]') { + return 'uint8clampedarray'; + } + if (type === '[object Int16Array]') { + return 'int16array'; + } + if (type === '[object Uint16Array]') { + return 'uint16array'; + } + if (type === '[object Int32Array]') { + return 'int32array'; + } + if (type === '[object Uint32Array]') { + return 'uint32array'; + } + if (type === '[object Float32Array]') { + return 'float32array'; } - - 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); + if (type === '[object Float64Array]') { + return 'float64array'; } - return thisArg; + + // must be a plain object + return 'object'; }; /***/ }), -/* 562 */ +/* 590 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var util = __webpack_require__(111); -var visit = __webpack_require__(561); +var isExtendable = __webpack_require__(591); +var forIn = __webpack_require__(592); + +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; +} /** - * Map `visit` over an array of objects. + * Copy properties from the source object to the + * target object. * - * @param {Object} `collection` The context in which to invoke `method` - * @param {String} `method` Name of the method to call on `collection` - * @param {Object} `arr` Array of objects. + * @param {*} `val` + * @param {String} `key` */ -module.exports = function mapVisit(collection, method, val) { - if (isObject(val)) { - return visit.apply(null, arguments); +function copy(val, key) { + if (!isValidKey(key)) { + return; } - if (!Array.isArray(val)) { - throw new TypeError('expected an array: ' + util.inspect(val)); + var obj = this[key]; + if (isObject(val) && isObject(obj)) { + mixinDeep(obj, val); + } else { + this[key] = val; } +} - var args = [].slice.call(arguments, 3); - - for (var i = 0; i < val.length; i++) { - var ele = val[i]; - if (isObject(ele)) { - visit.apply(null, [collection, method, ele].concat(args)); - } else { - collection[method].apply(collection, [ele].concat(args)); - } - } -}; +/** + * Returns true if `val` is an object or function. + * + * @param {any} val + * @return {Boolean} + */ function isObject(val) { - return val && (typeof val === 'function' || (!Array.isArray(val) && typeof val === 'object')); + return isExtendable(val) && !Array.isArray(val); } +/** + * Returns true if `key` is a valid key to use when extending objects. + * + * @param {String} `key` + * @return {Boolean} + */ + +function isValidKey(key) { + return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; +}; + +/** + * Expose `mixinDeep` + */ + +module.exports = mixinDeep; + /***/ }), -/* 563 */ +/* 591 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * to-object-path + * is-extendable * - * 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__(540); +var isPlainObject = __webpack_require__(543); -module.exports = function toPath(args) { - if (typeOf(args) !== 'arguments') { - args = arguments; - } - return filter(args).join('.'); +module.exports = function isExtendable(val) { + return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); }; -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; -} - /***/ }), -/* 564 */ +/* 592 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; +/*! + * for-in + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ -var isObject = __webpack_require__(526); -var union = __webpack_require__(565); -var get = __webpack_require__(566); -var set = __webpack_require__(567); -module.exports = function unionValue(obj, prop, value) { - if (!isObject(obj)) { - throw new TypeError('union-value expects the first argument to be an object.'); +module.exports = function forIn(obj, fn, thisArg) { + for (var key in obj) { + if (fn.call(thisArg, obj[key], key, obj) === false) { + break; + } } +}; - if (typeof prop !== 'string') { - throw new TypeError('union-value expects `prop` to be a string.'); - } - var arr = arrayify(get(obj, prop)); - set(obj, prop, union(arr, arrayify(value))); - return obj; -}; +/***/ }), +/* 593 */ +/***/ (function(module, exports) { -function arrayify(val) { - if (val === null || typeof val === 'undefined') { - return []; - } - if (Array.isArray(val)) { - return val; +/*! + * pascalcase + * + * Copyright (c) 2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +function pascalcase(str) { + if (typeof str !== 'string') { + throw new TypeError('expected a string.'); } - return [val]; + 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; + /***/ }), -/* 565 */ +/* 594 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = function union(init) { - if (!Array.isArray(init)) { - throw new TypeError('arr-union expects the first argument to be an array.'); - } +var util = __webpack_require__(112); +var utils = __webpack_require__(595); - var len = arguments.length; - var i = 0; +/** + * Expose class utils + */ - while (++i < len) { - var arg = arguments[i]; - if (!arg) continue; +var cu = module.exports; - if (!Array.isArray(arg)) { - arg = [arg]; - } +/** + * Expose class utils: `cu` + */ - for (var j = 0; j < arg.length; j++) { - var ele = arg[j]; +cu.isObject = function isObject(val) { + return utils.isObj(val) || typeof val === 'function'; +}; - if (init.indexOf(ele) >= 0) { - continue; +/** + * 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 + */ + +cu.has = function has(obj, val) { + val = cu.arrayify(val); + var len = val.length; + + if (cu.isObject(obj)) { + for (var key in obj) { + if (val.indexOf(key) > -1) { + return true; } - init.push(ele); } + + var keys = cu.nativeKeys(obj); + return cu.has(keys, val); } - return init; -}; + if (Array.isArray(obj)) { + var arr = obj; + while (len--) { + if (arr.indexOf(val[len]) > -1) { + return true; + } + } + return false; + } -/***/ }), -/* 566 */ -/***/ (function(module, exports) { + throw new TypeError('expected an array or object.'); +}; -/*! - * get-value +/** + * Returns true if an array or object has all of the given values. * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. + * ```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 */ -module.exports = function(obj, prop, a, b, c) { - if (!isObject(obj) || !prop) { - return obj; +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; +}; - 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); +/** + * Cast the given value to an array. + * + * ```js + * cu.arrayify('foo'); + * //=> ['foo'] + * + * cu.arrayify(['foo']); + * //=> ['foo'] + * ``` + * + * @param {String|Array} `val` + * @return {Array} + * @api public + */ - if (prop in obj) { - return obj[prop]; - } +cu.arrayify = function arrayify(val) { + return val ? (Array.isArray(val) ? val : [val]) : []; +}; - var segs = prop.split('.'); - var len = segs.length; - var i = -1; +/** + * Noop + */ - while (obj && (++i < len)) { - var key = segs[i]; - while (key[key.length - 1] === '\\') { - key = key.slice(0, -1) + '.' + segs[++i]; - } - obj = obj[key]; - } - return obj; +cu.noop = function noop() { + return; }; -function isObject(val) { - return val !== null && (typeof val === 'object' || typeof val === 'function'); -} +/** + * Returns the first argument passed to the function. + */ -function toString(val) { - if (!val) return ''; - if (Array.isArray(val)) { - return val.join('.'); - } +cu.identity = function identity(val) { return val; -} - - -/***/ }), -/* 567 */ -/***/ (function(module, exports, __webpack_require__) { +}; -"use strict"; -/*! - * set-value +/** + * Returns true if a value has a `contructor` * - * Copyright (c) 2014-2015, 2017, Jon Schlinkert. - * Released under the MIT License. + * ```js + * cu.hasConstructor({}); + * //=> true + * + * cu.hasConstructor(Object.create(null)); + * //=> false + * ``` + * @param {Object} `value` + * @return {Boolean} + * @api public */ +cu.hasConstructor = function hasConstructor(val) { + return cu.isObject(val) && typeof val.constructor !== 'undefined'; +}; +/** + * Get the native `ownPropertyNames` from the constructor of the + * given `object`. An empty array is returned if the object does + * not have a constructor. + * + * ```js + * cu.nativeKeys({a: 'b', b: 'c', c: 'd'}) + * //=> ['a', 'b', 'c'] + * + * cu.nativeKeys(function(){}) + * //=> ['length', 'caller'] + * ``` + * + * @param {Object} `obj` Object that has a `constructor`. + * @return {Array} Array of keys. + * @api public + */ -var split = __webpack_require__(531); -var extend = __webpack_require__(525); -var isPlainObject = __webpack_require__(534); -var isObject = __webpack_require__(526); +cu.nativeKeys = function nativeKeys(val) { + if (!cu.hasConstructor(val)) return []; + return Object.getOwnPropertyNames(val); +}; -module.exports = function(obj, prop, val) { - if (!isObject(obj)) { - return obj; - } +/** + * Returns property descriptor `key` if it's an "own" property + * of the given object. + * + * ```js + * function App() {} + * Object.defineProperty(App.prototype, 'count', { + * get: function() { + * return Object.keys(this).length; + * } + * }); + * cu.getDescriptor(App.prototype, 'count'); + * // returns: + * // { + * // get: [Function], + * // set: undefined, + * // enumerable: false, + * // configurable: false + * // } + * ``` + * + * @param {Object} `obj` + * @param {String} `key` + * @return {Object} Returns descriptor `key` + * @api public + */ - if (Array.isArray(prop)) { - prop = [].concat.apply([], prop).join('.'); +cu.getDescriptor = function getDescriptor(obj, key) { + if (!cu.isObject(obj)) { + throw new TypeError('expected an object.'); } - - if (typeof prop !== 'string') { - return obj; + if (typeof key !== 'string') { + throw new TypeError('expected key to be a string.'); } + return Object.getOwnPropertyDescriptor(obj, key); +}; - 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; - } +/** + * Copy a descriptor from one object to another. + * + * ```js + * function App() {} + * Object.defineProperty(App.prototype, 'count', { + * get: function() { + * return Object.keys(this).length; + * } + * }); + * var obj = {}; + * cu.copyDescriptor(obj, App.prototype, 'count'); + * ``` + * @param {Object} `receiver` + * @param {Object} `provider` + * @param {String} `name` + * @return {Object} + * @api public + */ - if (isPlainObject(current[key]) && isPlainObject(val)) { - current[key] = extend({}, current[key], val); - } else { - current[key] = val; - } +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.'); } - return obj; + var val = cu.getDescriptor(provider, name); + if (val) Object.defineProperty(receiver, name, val); }; -function isValidKey(key) { - return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; -} +/** + * 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 + */ + +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); + while (len--) { + key = props[len]; -/***/ }), -/* 568 */ -/***/ (function(module, exports, __webpack_require__) { + 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); + } + } +}; -"use strict"; -/*! - * unset-value +/** + * 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 isObject = __webpack_require__(535); -var has = __webpack_require__(569); - -module.exports = function unset(obj, prop) { - if (!isObject(obj)) { - throw new TypeError('expected an object.'); +cu.inherit = function inherit(receiver, provider, omit) { + if (!cu.isObject(receiver)) { + throw new TypeError('expected receiving object to be an object.'); } - if (obj.hasOwnProperty(prop)) { - delete obj[prop]; - return true; + if (!cu.isObject(provider)) { + throw new TypeError('expected providing object to be an object.'); } - 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]); + var keys = []; + for (var key in provider) { + keys.push(key); + receiver[key] = provider[key]; } - return true; -}; + keys = keys.concat(cu.arrayify(omit)); -/***/ }), -/* 569 */ -/***/ (function(module, exports, __webpack_require__) { + var a = provider.prototype || provider; + var b = receiver.prototype || receiver; + cu.copy(b, a, keys); +}; -"use strict"; -/*! - * has-value +/** + * Returns a function for extending the static properties, + * prototype properties, and descriptors from the `Parent` + * constructor onto `Child` constructors. * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. + * ```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 */ +cu.extend = function() { + // keep it lazy, instead of assigning to `cu.extend` + return utils.staticExtend.apply(null, arguments); +}; +/** + * 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 isObject = __webpack_require__(570); -var hasValues = __webpack_require__(572); -var get = __webpack_require__(566); - -module.exports = function(obj, prop, noZero) { - if (isObject(obj)) { - return hasValues(get(obj, prop), noZero); - } - return hasValues(obj, prop); +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); + }; }; /***/ }), -/* 570 */ +/* 595 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * isobject - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ +var utils = {}; -var isArray = __webpack_require__(571); -module.exports = function isObject(val) { - return val != null && typeof val === 'object' && isArray(val) === false; -}; +/** + * Lazily required module dependencies + */ -/***/ }), -/* 571 */ -/***/ (function(module, exports) { +utils.union = __webpack_require__(579); +utils.define = __webpack_require__(596); +utils.isObj = __webpack_require__(534); +utils.staticExtend = __webpack_require__(603); -var toString = {}.toString; -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; -}; +/** + * Expose `utils` + */ + +module.exports = utils; /***/ }), -/* 572 */ +/* 596 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * has-values + * define-property * - * Copyright (c) 2014-2015, Jon Schlinkert. + * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. */ -module.exports = function hasValue(o, noZero) { - if (o === null || o === undefined) { - return false; - } - - if (typeof o === 'boolean') { - return true; - } +var isDescriptor = __webpack_require__(597); - if (typeof o === 'number') { - if (o === 0 && noZero === true) { - return false; - } - return true; +module.exports = function defineProperty(obj, prop, val) { + if (typeof obj !== 'object' && typeof obj !== 'function') { + throw new TypeError('expected an object or function.'); } - if (o.length !== undefined) { - return o.length !== 0; + if (typeof prop !== 'string') { + throw new TypeError('expected `prop` to be a string.'); } - for (var key in o) { - if (o.hasOwnProperty(key)) { - return true; - } + if (isDescriptor(val) && ('set' in val || 'get' in val)) { + return Object.defineProperty(obj, prop, val); } - return false; -}; - - -/***/ }), -/* 573 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * has-value - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Licensed under the MIT License. - */ - - -var isObject = __webpack_require__(535); -var hasValues = __webpack_require__(574); -var get = __webpack_require__(566); - -module.exports = function(val, prop) { - return hasValues(isObject(val) && prop ? get(val, prop) : val); + return Object.defineProperty(obj, prop, { + configurable: true, + enumerable: false, + writable: true, + value: val + }); }; /***/ }), -/* 574 */ +/* 597 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * has-values + * is-descriptor * - * Copyright (c) 2014-2015, 2017, Jon Schlinkert. + * Copyright (c) 2015-2017, Jon Schlinkert. * Released under the MIT License. */ -var typeOf = __webpack_require__(575); -var isNumber = __webpack_require__(539); +var typeOf = __webpack_require__(598); +var isAccessor = __webpack_require__(599); +var isData = __webpack_require__(601); -module.exports = function hasValue(val) { - // is-number checks for NaN and other edge cases - if (isNumber(val)) { - return true; +module.exports = function isDescriptor(obj, key) { + if (typeOf(obj) !== 'object') { + return false; } - - 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; - } + if ('get' in obj) { + return isAccessor(obj, key); } + return isData(obj, key); }; /***/ }), -/* 575 */ -/***/ (function(module, exports, __webpack_require__) { +/* 598 */ +/***/ (function(module, exports) { -var isBuffer = __webpack_require__(522); var toString = Object.prototype.toString; /** @@ -65079,8 +68546,10 @@ var toString = Object.prototype.toString; */ module.exports = function kindOf(val) { + var type = typeof val; + // primitivies - if (typeof val === 'undefined') { + if (type === 'undefined') { return 'undefined'; } if (val === null) { @@ -65089,15 +68558,18 @@ module.exports = function kindOf(val) { if (val === true || val === false || val instanceof Boolean) { return 'boolean'; } - if (typeof val === 'string' || val instanceof String) { + if (type === 'string' || val instanceof String) { return 'string'; } - if (typeof val === 'number' || val instanceof Number) { + if (type === 'number' || val instanceof Number) { return 'number'; } // functions - if (typeof val === 'function' || val instanceof Function) { + if (type === 'function' || val instanceof Function) { + if (typeof val.constructor.name !== 'undefined' && val.constructor.name.slice(0, 9) === 'Generator') { + return 'generatorfunction'; + } return 'function'; } @@ -65115,7 +68587,7 @@ module.exports = function kindOf(val) { } // other objects - var type = toString.call(val); + type = toString.call(val); if (type === '[object RegExp]') { return 'regexp'; @@ -65154,7 +68626,20 @@ module.exports = function kindOf(val) { if (type === '[object Symbol]') { return 'symbol'; } - + + if (type === '[object Map Iterator]') { + return 'mapiterator'; + } + if (type === '[object Set Iterator]') { + return 'setiterator'; + } + if (type === '[object String Iterator]') { + return 'stringiterator'; + } + if (type === '[object Array Iterator]') { + return 'arrayiterator'; + } + // typed arrays if (type === '[object Int8Array]') { return 'int8array'; @@ -65188,551 +68673,402 @@ module.exports = function kindOf(val) { return 'object'; }; - -/***/ }), -/* 576 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var isExtendable = __webpack_require__(577); -var forIn = __webpack_require__(578); - -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; -} - -/** - * Copy properties from the source object to the - * target object. - * - * @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. - * - * @param {any} val - * @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 isObject(val) { - return isExtendable(val) && !Array.isArray(val); +function isBuffer(val) { + return val.constructor + && typeof val.constructor.isBuffer === 'function' + && val.constructor.isBuffer(val); } -/** - * Returns true if `key` is a valid key to use when extending objects. - * - * @param {String} `key` - * @return {Boolean} - */ - -function isValidKey(key) { - return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; -}; - -/** - * Expose `mixinDeep` - */ - -module.exports = mixinDeep; - - -/***/ }), -/* 577 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/*! - * is-extendable - * - * Copyright (c) 2015-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -var isPlainObject = __webpack_require__(534); - -module.exports = function isExtendable(val) { - return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); -}; - /***/ }), -/* 578 */ +/* 599 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! - * for-in - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - - - -module.exports = function forIn(obj, fn, thisArg) { - for (var key in obj) { - if (fn.call(thisArg, obj[key], key, obj) === false) { - break; - } - } -}; - - -/***/ }), -/* 579 */ -/***/ (function(module, exports) { - -/*! - * pascalcase + * is-accessor-descriptor * * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. */ -function pascalcase(str) { - if (typeof str !== 'string') { - throw new TypeError('expected a string.'); - } - str = str.replace(/([A-Z])/g, ' $1'); - if (str.length === 1) { return str.toUpperCase(); } - str = str.replace(/^[\W_]+|[\W_]+$/g, '').toLowerCase(); - str = str.charAt(0).toUpperCase() + str.slice(1); - return str.replace(/[\W_]+(\w|$)/g, function (_, ch) { - return ch.toUpperCase(); - }); -} - -module.exports = pascalcase; - - -/***/ }), -/* 580 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var util = __webpack_require__(111); -var utils = __webpack_require__(581); - -/** - * Expose class utils - */ -var cu = module.exports; -/** - * Expose class utils: `cu` - */ +var typeOf = __webpack_require__(600); -cu.isObject = function isObject(val) { - return utils.isObj(val) || typeof val === 'function'; +// accessor descriptor properties +var accessor = { + get: 'function', + set: 'function', + configurable: 'boolean', + enumerable: 'boolean' }; -/** - * 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 - */ - -cu.has = function has(obj, val) { - val = cu.arrayify(val); - var len = val.length; +function isAccessorDescriptor(obj, prop) { + if (typeof prop === 'string') { + var val = Object.getOwnPropertyDescriptor(obj, prop); + return typeof val !== 'undefined'; + } - if (cu.isObject(obj)) { - for (var key in obj) { - if (val.indexOf(key) > -1) { - return true; - } - } + if (typeOf(obj) !== 'object') { + return false; + } - var keys = cu.nativeKeys(obj); - return cu.has(keys, val); + if (has(obj, 'value') || has(obj, 'writable')) { + return false; } - if (Array.isArray(obj)) { - var arr = obj; - while (len--) { - if (arr.indexOf(val[len]) > -1) { - return true; - } - } + if (!has(obj, 'get') || typeof obj.get !== 'function') { return false; } - throw new TypeError('expected an array or object.'); -}; + // tldr: it's valid to have "set" be undefined + // "set" might be undefined if `Object.getOwnPropertyDescriptor` + // was used to get the value, and only `get` was defined by the user + if (has(obj, 'set') && typeof obj[key] !== 'function' && typeof obj[key] !== 'undefined') { + return false; + } -/** - * Returns true if 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 - */ + for (var key in obj) { + if (!accessor.hasOwnProperty(key)) { + continue; + } -cu.hasAll = function hasAll(val, values) { - values = cu.arrayify(values); - var len = values.length; - while (len--) { - if (!cu.has(val, values[len])) { + if (typeOf(obj[key]) === accessor[key]) { + continue; + } + + if (typeof obj[key] !== 'undefined') { return false; } } 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 - */ +} -cu.arrayify = function arrayify(val) { - return val ? (Array.isArray(val) ? val : [val]) : []; -}; +function has(obj, key) { + return {}.hasOwnProperty.call(obj, key); +} /** - * Noop + * Expose `isAccessorDescriptor` */ -cu.noop = function noop() { - return; -}; - -/** - * Returns the first argument passed to the function. - */ +module.exports = isAccessorDescriptor; -cu.identity = function identity(val) { - return val; -}; -/** - * 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 - */ +/***/ }), +/* 600 */ +/***/ (function(module, exports, __webpack_require__) { -cu.hasConstructor = function hasConstructor(val) { - return cu.isObject(val) && typeof val.constructor !== 'undefined'; -}; +var isBuffer = __webpack_require__(560); +var toString = Object.prototype.toString; /** - * 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'] - * ``` + * Get the native `typeof` a value. * - * @param {Object} `obj` Object that has a `constructor`. - * @return {Array} Array of keys. - * @api public + * @param {*} `val` + * @return {*} Native javascript type */ -cu.nativeKeys = function nativeKeys(val) { - if (!cu.hasConstructor(val)) return []; - return Object.getOwnPropertyNames(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'; + } -/** - * 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 - */ + // functions + if (typeof val === 'function' || val instanceof Function) { + return 'function'; + } -cu.getDescriptor = function getDescriptor(obj, key) { - if (!cu.isObject(obj)) { - throw new TypeError('expected an object.'); + // array + if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { + return 'array'; } - if (typeof key !== 'string') { - throw new TypeError('expected key to be a string.'); + + // check for instances of RegExp and Date before calling `toString` + if (val instanceof RegExp) { + return 'regexp'; + } + if (val instanceof Date) { + return 'date'; } - return Object.getOwnPropertyDescriptor(obj, key); -}; -/** - * Copy a descriptor from one object to another. - * - * ```js - * function App() {} - * Object.defineProperty(App.prototype, 'count', { - * get: function() { - * return Object.keys(this).length; - * } - * }); - * var obj = {}; - * cu.copyDescriptor(obj, App.prototype, 'count'); - * ``` - * @param {Object} `receiver` - * @param {Object} `provider` - * @param {String} `name` - * @return {Object} - * @api public - */ + // other objects + var type = toString.call(val); -cu.copyDescriptor = function copyDescriptor(receiver, provider, name) { - if (!cu.isObject(receiver)) { - throw new TypeError('expected receiving object to be an object.'); + if (type === '[object RegExp]') { + return 'regexp'; } - if (!cu.isObject(provider)) { - throw new TypeError('expected providing object to be an object.'); + if (type === '[object Date]') { + return 'date'; } - if (typeof name !== 'string') { - throw new TypeError('expected name to be a string.'); + if (type === '[object Arguments]') { + return 'arguments'; + } + if (type === '[object Error]') { + return 'error'; } - 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 - */ + // buffer + if (isBuffer(val)) { + return 'buffer'; + } -cu.copy = function copy(receiver, provider, omit) { - if (!cu.isObject(receiver)) { - throw new TypeError('expected receiving object to be an object.'); + // es6: Map, WeakMap, Set, WeakSet + if (type === '[object Set]') { + return 'set'; } - if (!cu.isObject(provider)) { - throw new TypeError('expected providing object to be an object.'); + if (type === '[object WeakSet]') { + return 'weakset'; + } + if (type === '[object Map]') { + return 'map'; + } + if (type === '[object WeakMap]') { + return 'weakmap'; + } + if (type === '[object Symbol]') { + return 'symbol'; } - var props = Object.getOwnPropertyNames(provider); - var keys = Object.keys(provider); - var len = props.length, - key; - omit = cu.arrayify(omit); - - while (len--) { - key = props[len]; - if (cu.has(keys, key)) { - utils.define(receiver, key, provider[key]); - } else if (!(key in receiver) && !cu.has(omit, key)) { - cu.copyDescriptor(receiver, provider, key); - } + // typed arrays + if (type === '[object Int8Array]') { + return 'int8array'; + } + if (type === '[object Uint8Array]') { + return 'uint8array'; + } + if (type === '[object Uint8ClampedArray]') { + return 'uint8clampedarray'; + } + if (type === '[object Int16Array]') { + return 'int16array'; + } + if (type === '[object Uint16Array]') { + return 'uint16array'; + } + if (type === '[object Int32Array]') { + return 'int32array'; + } + if (type === '[object Uint32Array]') { + return 'uint32array'; } + if (type === '[object Float32Array]') { + return 'float32array'; + } + if (type === '[object Float64Array]') { + return 'float64array'; + } + + // must be a plain object + return 'object'; }; -/** - * Inherit the static properties, prototype properties, and descriptors - * from of an object. + +/***/ }), +/* 601 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; +/*! + * is-data-descriptor * - * @param {Object} `receiver` - * @param {Object} `provider` - * @param {String|Array} `omit` One or more properties to omit - * @return {Object} - * @api public + * Copyright (c) 2015, Jon Schlinkert. + * Licensed 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.'); + + +var typeOf = __webpack_require__(602); + +// data descriptor properties +var data = { + configurable: 'boolean', + enumerable: 'boolean', + writable: 'boolean' +}; + +function isDataDescriptor(obj, prop) { + if (typeOf(obj) !== 'object') { + return false; } - if (!cu.isObject(provider)) { - throw new TypeError('expected providing object to be an object.'); + + if (typeof prop === 'string') { + var val = Object.getOwnPropertyDescriptor(obj, prop); + return typeof val !== 'undefined'; } - var keys = []; - for (var key in provider) { - keys.push(key); - receiver[key] = provider[key]; + if (!('value' in obj) && !('writable' in obj)) { + return false; } - keys = keys.concat(cu.arrayify(omit)); + for (var key in obj) { + if (key === 'value') continue; - var a = provider.prototype || provider; - var b = receiver.prototype || receiver; - cu.copy(b, a, keys); -}; + if (!data.hasOwnProperty(key)) { + continue; + } -/** - * 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(obj[key]) === data[key]) { + continue; + } -cu.extend = function() { - // keep it lazy, instead of assigning to `cu.extend` - return utils.staticExtend.apply(null, arguments); -}; + if (typeof obj[key] !== 'undefined') { + return false; + } + } + return true; +} /** - * Bubble up events emitted from static methods on the Parent ctor. - * - * @param {Object} `Parent` - * @param {Array} `events` Event names to bubble up - * @api public + * Expose `isDataDescriptor` */ -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); - }; -}; +module.exports = isDataDescriptor; /***/ }), -/* 581 */ +/* 602 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +var isBuffer = __webpack_require__(560); +var toString = Object.prototype.toString; +/** + * Get the native `typeof` a value. + * + * @param {*} `val` + * @return {*} Native javascript type + */ -var utils = {}; +module.exports = function kindOf(val) { + // primitivies + if (typeof val === 'undefined') { + return 'undefined'; + } + if (val === null) { + return 'null'; + } + if (val === true || val === false || val instanceof Boolean) { + return 'boolean'; + } + if (typeof val === 'string' || val instanceof String) { + return 'string'; + } + if (typeof val === 'number' || val instanceof Number) { + return 'number'; + } + // functions + if (typeof val === 'function' || val instanceof Function) { + return 'function'; + } + // array + if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) { + return 'array'; + } -/** - * Lazily required module dependencies - */ + // check for instances of RegExp and Date before calling `toString` + if (val instanceof RegExp) { + return 'regexp'; + } + if (val instanceof Date) { + return 'date'; + } -utils.union = __webpack_require__(565); -utils.define = __webpack_require__(517); -utils.isObj = __webpack_require__(535); -utils.staticExtend = __webpack_require__(582); + // 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'; + } -/** - * Expose `utils` - */ + // buffer + if (isBuffer(val)) { + return 'buffer'; + } -module.exports = utils; + // es6: Map, WeakMap, Set, WeakSet + if (type === '[object Set]') { + return 'set'; + } + if (type === '[object WeakSet]') { + return 'weakset'; + } + if (type === '[object Map]') { + return 'map'; + } + if (type === '[object WeakMap]') { + return 'weakmap'; + } + if (type === '[object Symbol]') { + return 'symbol'; + } + + // typed arrays + if (type === '[object Int8Array]') { + return 'int8array'; + } + if (type === '[object Uint8Array]') { + return 'uint8array'; + } + if (type === '[object Uint8ClampedArray]') { + return 'uint8clampedarray'; + } + if (type === '[object Int16Array]') { + return 'int16array'; + } + if (type === '[object Uint16Array]') { + return 'uint16array'; + } + if (type === '[object Int32Array]') { + return 'int32array'; + } + if (type === '[object Uint32Array]') { + return 'uint32array'; + } + if (type === '[object Float32Array]') { + return 'float32array'; + } + if (type === '[object Float64Array]') { + return 'float64array'; + } + + // must be a plain object + return 'object'; +}; /***/ }), -/* 582 */ +/* 603 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -65745,9 +69081,9 @@ module.exports = utils; -var copy = __webpack_require__(583); -var define = __webpack_require__(517); -var util = __webpack_require__(111); +var copy = __webpack_require__(604); +var define = __webpack_require__(596); +var util = __webpack_require__(112); /** * Returns a function for extending the static properties, @@ -65829,15 +69165,15 @@ module.exports = extend; /***/ }), -/* 583 */ +/* 604 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(540); -var copyDescriptor = __webpack_require__(584); -var define = __webpack_require__(517); +var typeOf = __webpack_require__(559); +var copyDescriptor = __webpack_require__(605); +var define = __webpack_require__(596); /** * Copy static properties, prototype properties, and descriptors from one object to another. @@ -66010,7 +69346,7 @@ module.exports.has = has; /***/ }), -/* 584 */ +/* 605 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66098,16 +69434,16 @@ function isObject(val) { /***/ }), -/* 585 */ +/* 606 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(586); -var define = __webpack_require__(517); -var debug = __webpack_require__(588)('snapdragon:compiler'); -var utils = __webpack_require__(594); +var use = __webpack_require__(607); +var define = __webpack_require__(596); +var debug = __webpack_require__(609)('snapdragon:compiler'); +var utils = __webpack_require__(615); /** * Create a new `Compiler` with the given `options`. @@ -66261,7 +69597,7 @@ Compiler.prototype = { // source map support if (opts.sourcemap) { - var sourcemaps = __webpack_require__(613); + var sourcemaps = __webpack_require__(634); sourcemaps(this); this.mapVisit(this.ast.nodes); this.applySourceMaps(); @@ -66282,7 +69618,7 @@ module.exports = Compiler; /***/ }), -/* 586 */ +/* 607 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66295,7 +69631,7 @@ module.exports = Compiler; -var utils = __webpack_require__(587); +var utils = __webpack_require__(608); module.exports = function base(app, opts) { if (!utils.isObject(app) && typeof app !== 'function') { @@ -66410,7 +69746,7 @@ module.exports = function base(app, opts) { /***/ }), -/* 587 */ +/* 608 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66424,8 +69760,8 @@ var utils = {}; * Lazily required module dependencies */ -utils.define = __webpack_require__(517); -utils.isObject = __webpack_require__(535); +utils.define = __webpack_require__(596); +utils.isObject = __webpack_require__(534); utils.isString = function(val) { @@ -66440,7 +69776,7 @@ module.exports = utils; /***/ }), -/* 588 */ +/* 609 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -66449,14 +69785,14 @@ module.exports = utils; */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(589); + module.exports = __webpack_require__(610); } else { - module.exports = __webpack_require__(592); + module.exports = __webpack_require__(613); } /***/ }), -/* 589 */ +/* 610 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -66465,7 +69801,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(590); +exports = module.exports = __webpack_require__(611); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -66647,7 +69983,7 @@ function localstorage() { /***/ }), -/* 590 */ +/* 611 */ /***/ (function(module, exports, __webpack_require__) { @@ -66663,7 +69999,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(591); +exports.humanize = __webpack_require__(612); /** * The currently active debug mode names, and names to skip. @@ -66855,7 +70191,7 @@ function coerce(val) { /***/ }), -/* 591 */ +/* 612 */ /***/ (function(module, exports) { /** @@ -66945,1046 +70281,405 @@ function parse(str) { case 'secs': case 'sec': case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - default: - return undefined; - } -} - -/** - * 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'; - } - 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 - */ - -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 (ms < n * 1.5) { - return Math.floor(ms / n) + ' ' + name; - } - return Math.ceil(ms / n) + ' ' + name + 's'; -} - - -/***/ }), -/* 592 */ -/***/ (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()`. - * - * Expose `debug()` as the module. - */ - -exports = module.exports = __webpack_require__(590); -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]; - -/** - * Build up the default `inspectOpts` object from the environment variables. - * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js - */ - -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; -}, {}); - -/** - * 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 - */ - -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 stdout a TTY? Colored output is enabled when `true`. - */ - -function useColors() { - return 'colors' in exports.inspectOpts - ? Boolean(exports.inspectOpts.colors) - : tty.isatty(fd); -} - -/** - * 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(' '); -}; - -/** - * Map %o to `util.inspect()`, allowing multiple lines if needed. - */ - -exports.formatters.O = function(v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); -}; - -/** - * Adds ANSI color escape codes if enabled. - * - * @api public - */ - -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'; - - 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]; - } -} - -/** - * Invokes `util.format()` with the specified arguments and writes to `stream`. - */ - -function log() { - return stream.write(util.format.apply(util, arguments) + '\n'); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ - -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; - } -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - return process.env.DEBUG; -} - -/** - * Copied from `node/src/node.js`. - * - * 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. - */ - -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__(133); - stream = new fs.SyncWriteStream(fd, { autoClose: false }); - stream._type = 'fs'; - break; - - case 'PIPE': - case 'TCP': - var net = __webpack_require__(593); - 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; -} - -/** - * Init logic for `debug` instances. - * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. - */ - -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]]; - } -} - -/** - * Enable namespaces listed in `process.env.DEBUG` initially. - */ - -exports.enable(load()); - - -/***/ }), -/* 593 */ -/***/ (function(module, exports) { - -module.exports = require("net"); - -/***/ }), -/* 594 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -/** - * Module dependencies - */ - -exports.extend = __webpack_require__(525); -exports.SourceMap = __webpack_require__(595); -exports.sourceMapResolve = __webpack_require__(606); - -/** - * Convert backslash in the given string to forward slashes - */ - -exports.unixify = function(fp) { - return fp.split(/\\+/).join('/'); -}; + return n * s; + case 'milliseconds': + case 'millisecond': + case 'msecs': + case 'msec': + case 'ms': + return n; + default: + return undefined; + } +} /** - * Return true if `val` is a non-empty string + * Short format for `ms`. * - * @param {String} `str` - * @return {Boolean} + * @param {Number} ms + * @return {String} + * @api private */ -exports.isString = function(str) { - return str && typeof str === 'string'; -}; +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'; +} /** - * Cast `val` to an array - * @return {Array} + * Long format for `ms`. + * + * @param {Number} ms + * @return {String} + * @api private */ -exports.arrayify = function(val) { - if (typeof val === 'string') return [val]; - return val ? (Array.isArray(val) ? val : [val]) : []; -}; +function fmtLong(ms) { + return plural(ms, d, 'day') || + plural(ms, h, 'hour') || + plural(ms, m, 'minute') || + plural(ms, s, 'second') || + ms + ' ms'; +} /** - * Get the last `n` element from the given `array` - * @param {Array} `array` - * @return {*} + * Pluralization helper. */ -exports.last = function(arr, n) { - return arr[arr.length - (n || 1)]; -}; +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'; +} /***/ }), -/* 595 */ +/* 613 */ /***/ (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 +/** + * Module dependencies. */ -exports.SourceMapGenerator = __webpack_require__(596).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(602).SourceMapConsumer; -exports.SourceNode = __webpack_require__(605).SourceNode; +var tty = __webpack_require__(122); +var util = __webpack_require__(112); -/***/ }), -/* 596 */ -/***/ (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 Node.js implementation of `debug()`. + * + * Expose `debug()` as the module. */ -var base64VLQ = __webpack_require__(597); -var util = __webpack_require__(599); -var ArraySet = __webpack_require__(600).ArraySet; -var MappingList = __webpack_require__(601).MappingList; +exports = module.exports = __webpack_require__(611); +exports.init = init; +exports.log = log; +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; /** - * 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. + * Colors. */ -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; -} -SourceMapGenerator.prototype._version = 3; +exports.colors = [6, 2, 3, 4, 5, 1]; /** - * Creates a new SourceMapGenerator based on a SourceMapConsumer + * Build up the default `inspectOpts` object from the environment variables. * - * @param aSourceMapConsumer The SourceMap. + * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js */ -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 - } - }; - if (mapping.source != null) { - newMapping.source = mapping.source; - if (sourceRoot != null) { - newMapping.source = util.relative(sourceRoot, newMapping.source); - } - - newMapping.original = { - line: mapping.originalLine, - column: mapping.originalColumn - }; +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() }); - if (mapping.name != null) { - newMapping.name = mapping.name; - } - } + // 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); - generator.addMapping(newMapping); - }); - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content != null) { - generator.setSourceContent(sourceFile, content); - } - }); - return generator; - }; + obj[prop] = val; + return obj; +}, {}); /** - * 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: + * The file descriptor to write the `debug()` calls to. + * Set the `DEBUG_FD` env variable to override with another value. i.e.: * - * - 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. + * $ DEBUG_FD=3 node script.js 3>debug.log */ -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); - - if (!this._skipValidation) { - this._validateMapping(generated, original, source, name); - } - if (source != null) { - source = String(source); - if (!this._sources.has(source)) { - this._sources.add(source); - } - } +var fd = parseInt(process.env.DEBUG_FD, 10) || 2; - if (name != null) { - name = String(name); - if (!this._names.has(name)) { - this._names.add(name); - } - } +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)')() +} - this._mappings.add({ - generatedLine: generated.line, - generatedColumn: generated.column, - originalLine: original != null && original.line, - originalColumn: original != null && original.column, - source: source, - name: name - }); - }; +var stream = 1 === fd ? process.stdout : + 2 === fd ? process.stderr : + createWritableStdioStream(fd); /** - * Set the source content for a source file. + * Is stdout a TTY? Colored output is enabled when `true`. */ -SourceMapGenerator.prototype.setSourceContent = - function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { - var source = aSourceFile; - if (this._sourceRoot != null) { - source = util.relative(this._sourceRoot, source); - } - 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; - } - } - }; +function useColors() { + return 'colors' in exports.inspectOpts + ? Boolean(exports.inspectOpts.colors) + : tty.isatty(fd); +} /** - * 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. + * Map %o to `util.inspect()`, all on a single line. */ -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); - } - - }, 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); - }; +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(' '); +}; /** - * 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. + * Map %o to `util.inspect()`, allowing multiple lines if needed. */ -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 - })); - } - }; +exports.formatters.O = function(v) { + this.inspectOpts.colors = this.useColors; + return util.inspect(v, this.inspectOpts); +}; /** - * Serialize the accumulated mappings in to the stream of base 64 VLQs - * specified by the source map format. + * Adds ANSI color escape codes if enabled. + * + * @api public */ -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 = '' - - 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 += ','; - } - } - - next += base64VLQ.encode(mapping.generatedColumn - - previousGeneratedColumn); - previousGeneratedColumn = mapping.generatedColumn; - if (mapping.source != null) { - sourceIdx = this._sources.indexOf(mapping.source); - next += base64VLQ.encode(sourceIdx - previousSource); - previousSource = sourceIdx; +function formatArgs(args) { + var name = this.namespace; + var useColors = this.useColors; - // lines are stored 0-based in SourceMap spec version 3 - next += base64VLQ.encode(mapping.originalLine - 1 - - previousOriginalLine); - previousOriginalLine = mapping.originalLine - 1; + if (useColors) { + var c = this.color; + var prefix = ' \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m'; - next += base64VLQ.encode(mapping.originalColumn - - previousOriginalColumn); - previousOriginalColumn = mapping.originalColumn; + 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]; + } +} - if (mapping.name != null) { - nameIdx = this._names.indexOf(mapping.name); - next += base64VLQ.encode(nameIdx - previousName); - previousName = nameIdx; - } - } +/** + * Invokes `util.format()` with the specified arguments and writes to `stream`. + */ - result += next; - } +function log() { + return stream.write(util.format.apply(util, arguments) + '\n'); +} - return result; - }; +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ -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); - }; +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; + } +} /** - * Externalize the source map. + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private */ -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 (this._sourceRoot != null) { - map.sourceRoot = this._sourceRoot; - } - if (this._sourcesContents) { - map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); - } - return map; - }; +function load() { + return process.env.DEBUG; +} /** - * Render the source map being generated to a string. + * Copied from `node/src/node.js`. + * + * 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. */ -SourceMapGenerator.prototype.toString = - function SourceMapGenerator_toString() { - return JSON.stringify(this.toJSON()); - }; -exports.SourceMapGenerator = SourceMapGenerator; +function createWritableStdioStream (fd) { + var stream; + var tty_wrap = process.binding('tty_wrap'); + // Note stream._type is used for test-module-load-list.js -/***/ }), -/* 597 */ -/***/ (function(module, exports, __webpack_require__) { + switch (tty_wrap.guessHandleType(fd)) { + case 'TTY': + stream = new tty.WriteStream(fd); + stream._type = 'tty'; -/* -*- 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. - */ + // 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; -var base64 = __webpack_require__(598); + case 'FILE': + var fs = __webpack_require__(134); + stream = new fs.SyncWriteStream(fd, { autoClose: false }); + stream._type = 'fs'; + break; -// 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 + case 'PIPE': + case 'TCP': + var net = __webpack_require__(614); + stream = new net.Socket({ + fd: fd, + readable: false, + writable: true + }); -var VLQ_BASE_SHIFT = 5; + // 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'; -// binary: 100000 -var VLQ_BASE = 1 << VLQ_BASE_SHIFT; + // 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; -// binary: 011111 -var VLQ_BASE_MASK = VLQ_BASE - 1; + default: + // Probably an error on in uv_guess_handle() + throw new Error('Implement me. Unknown stream file type!'); + } -// binary: 100000 -var VLQ_CONTINUATION_BIT = VLQ_BASE; + // For supporting legacy API we put the FD here. + stream.fd = fd; -/** - * 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; -} + stream._isStdio = true; -/** - * 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; + return stream; } /** - * Returns the base 64 VLQ encoded value. + * Init logic for `debug` instances. + * + * Create a new `inspectOpts` object in case `useColors` is set + * differently for a particular `debug` instance. */ -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; - } - encoded += base64.encode(digit); - } while (vlq > 0); +function init (debug) { + debug.inspectOpts = {}; - return encoded; -}; + var keys = Object.keys(exports.inspectOpts); + for (var i = 0; i < keys.length; i++) { + debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; + } +} /** - * 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. + * Enable namespaces listed in `process.env.DEBUG` initially. */ -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."); - } - digit = base64.decode(aStr.charCodeAt(aIndex++)); - if (digit === -1) { - throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); - } +exports.enable(load()); - 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; -}; +/***/ }), +/* 614 */ +/***/ (function(module, exports) { +module.exports = require("net"); /***/ }), -/* 598 */ -/***/ (function(module, exports) { +/* 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"; -var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); /** - * Encode an integer in the range of 0 to 63 to a single base 64 digit. + * Module dependencies */ -exports.encode = function (number) { - if (0 <= number && number < intToCharMap.length) { - return intToCharMap[number]; - } - throw new TypeError("Must be between 0 and 63: " + number); -}; + +exports.extend = __webpack_require__(549); +exports.SourceMap = __webpack_require__(616); +exports.sourceMapResolve = __webpack_require__(627); /** - * Decode a single base 64 character code digit to an integer. Returns -1 on - * failure. + * Convert backslash in the given string to forward slashes */ -exports.decode = function (charCode) { - var bigA = 65; // 'A' - var bigZ = 90; // 'Z' - var littleA = 97; // 'a' - var littleZ = 122; // 'z' +exports.unixify = function(fp) { + return fp.split(/\\+/).join('/'); +}; - var zero = 48; // '0' - var nine = 57; // '9' +/** + * Return true if `val` is a non-empty string + * + * @param {String} `str` + * @return {Boolean} + */ - var plus = 43; // '+' - var slash = 47; // '/' +exports.isString = function(str) { + return str && typeof str === 'string'; +}; - var littleOffset = 26; - var numberOffset = 52; +/** + * Cast `val` to an array + * @return {Array} + */ - // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ - if (bigA <= charCode && charCode <= bigZ) { - return (charCode - bigA); - } +exports.arrayify = function(val) { + if (typeof val === 'string') return [val]; + return val ? (Array.isArray(val) ? val : [val]) : []; +}; - // 26 - 51: abcdefghijklmnopqrstuvwxyz - if (littleA <= charCode && charCode <= littleZ) { - return (charCode - littleA + littleOffset); - } +/** + * Get the last `n` element from the given `array` + * @param {Array} `array` + * @return {*} + */ - // 52 - 61: 0123456789 - if (zero <= charCode && charCode <= nine) { - return (charCode - zero + numberOffset); - } +exports.last = function(arr, n) { + return arr[arr.length - (n || 1)]; +}; - // 62: + - if (charCode == plus) { - return 62; - } - // 63: / - if (charCode == slash) { - return 63; - } +/***/ }), +/* 616 */ +/***/ (function(module, exports, __webpack_require__) { - // Invalid base64 digit. - return -1; -}; +/* + * 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; /***/ }), -/* 599 */ -/***/ (function(module, exports) { +/* 617 */ +/***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ /* @@ -67993,420 +70688,419 @@ exports.decode = function (charCode) { * http://opensource.org/licenses/BSD-3-Clause */ -/** - * 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; - -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; +var base64VLQ = __webpack_require__(618); +var util = __webpack_require__(620); +var ArraySet = __webpack_require__(621).ArraySet; +var MappingList = __webpack_require__(622).MappingList; /** - * Normalizes a path, or the path portion of a URL: - * - * - Replaces consecutive slashes with one slash. - * - Removes unnecessary '.' parts. - * - Removes unnecessary '
/..' parts. - * - * Based on code in the Node.js 'path' core module. + * An instance of the SourceMapGenerator represents a source map which is + * being built incrementally. You may pass an object with the following + * properties: * - * @param aPath The path or url to normalize. + * - file: The filename of the generated source. + * - sourceRoot: A root for all relative URLs in this source map. */ -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('/'); - - if (path === '') { - path = isAbsolute ? '/' : '.'; - } - - if (url) { - url.path = path; - return urlGenerate(url); +function SourceMapGenerator(aArgs) { + if (!aArgs) { + aArgs = {}; } - return path; + 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; } -exports.normalize = normalize; + +SourceMapGenerator.prototype._version = 3; /** - * Joins two paths/URLs. - * - * @param aRoot The root path or URL. - * @param aPath The path or URL to be joined with the root. + * Creates a new SourceMapGenerator based on a SourceMapConsumer * - * - 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. + * @param aSourceMapConsumer The SourceMap. */ -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); - } - - if (aPathUrl || aPath.match(dataUrlRegexp)) { - return aPath; - } +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 + } + }; - // `join('http://', 'www.example.com')` - if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { - aRootUrl.host = aPath; - return urlGenerate(aRootUrl); - } + if (mapping.source != null) { + newMapping.source = mapping.source; + if (sourceRoot != null) { + newMapping.source = util.relative(sourceRoot, newMapping.source); + } - var joined = aPath.charAt(0) === '/' - ? aPath - : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); + newMapping.original = { + line: mapping.originalLine, + column: mapping.originalColumn + }; - if (aRootUrl) { - aRootUrl.path = joined; - return urlGenerate(aRootUrl); - } - return joined; -} -exports.join = join; + if (mapping.name != null) { + newMapping.name = mapping.name; + } + } -exports.isAbsolute = function (aPath) { - return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); -}; + generator.addMapping(newMapping); + }); + aSourceMapConsumer.sources.forEach(function (sourceFile) { + var content = aSourceMapConsumer.sourceContentFor(sourceFile); + if (content != null) { + generator.setSourceContent(sourceFile, content); + } + }); + return generator; + }; /** - * Make a path relative to a URL or another path. + * 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: * - * @param aRoot The root path or URL. - * @param aPath The path or URL to be made relative to aRoot. + * - 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 relative(aRoot, aPath) { - if (aRoot === "") { - aRoot = "."; - } - - aRoot = aRoot.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); - // 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; + if (!this._skipValidation) { + this._validateMapping(generated, original, source, name); } - // 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; + if (source != null) { + source = String(source); + if (!this._sources.has(source)) { + this._sources.add(source); + } } - ++level; - } + if (name != null) { + name = String(name); + if (!this._names.has(name)) { + this._names.add(name); + } + } - // 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; + this._mappings.add({ + generatedLine: generated.line, + generatedColumn: generated.column, + originalLine: original != null && original.line, + originalColumn: original != null && original.column, + source: source, + name: name + }); + }; -var supportsNullProto = (function () { - var obj = Object.create(null); - return !('__proto__' in obj); -}()); +/** + * 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); + } -function identity (s) { - return s; -} + 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; + } + } + }; /** - * 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 + * 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 String aStr + * @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. */ -function toSetString(aStr) { - if (isProtoString(aStr)) { - return '$' + aStr; - } - - return aStr; -} -exports.toSetString = supportsNullProto ? identity : toSetString; - -function fromSetString(aStr) { - if (isProtoString(aStr)) { - return aStr.slice(1); - } - - return aStr; -} -exports.fromSetString = supportsNullProto ? identity : fromSetString; - -function isProtoString(s) { - if (!s) { - return false; - } +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(); - var length = s.length; + // 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; + } + } + } - if (length < 9 /* "__proto__".length */) { - return false; - } + var source = mapping.source; + if (source != null && !newSources.has(source)) { + newSources.add(source); + } - 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; - } + var name = mapping.name; + if (name != null && !newNames.has(name)) { + newNames.add(name); + } - for (var i = length - 10; i >= 0; i--) { - if (s.charCodeAt(i) !== 36 /* '$' */) { - return false; - } - } + }, this); + this._sources = newSources; + this._names = newNames; - return true; -} + // 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); + }; /** - * Comparator between two mappings where the original positions are compared. + * A mapping can have one of the three levels of data: * - * 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. + * 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. */ -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; - } - - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp !== 0) { - return cmp; - } - - cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp !== 0) { - return cmp; - } +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.' + ); + } - return mappingA.name - mappingB.name; -} -exports.compareByOriginalPositions = compareByOriginalPositions; + 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 + })); + } + }; /** - * Comparator between two mappings with deflated source and name indices where - * the generated positions are compared. - * - * 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. + * Serialize the accumulated mappings in to the stream of base 64 VLQs + * specified by the source map format. */ -function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { - var cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp !== 0) { - return cmp; - } +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; - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp !== 0 || onlyCompareGenerated) { - return cmp; - } + var mappings = this._mappings.toArray(); + for (var i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + next = '' - cmp = mappingA.source - mappingB.source; - if (cmp !== 0) { - return cmp; - } + 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 += ','; + } + } - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp !== 0) { - return cmp; - } + next += base64VLQ.encode(mapping.generatedColumn + - previousGeneratedColumn); + previousGeneratedColumn = mapping.generatedColumn; - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp !== 0) { - return cmp; - } + if (mapping.source != null) { + sourceIdx = this._sources.indexOf(mapping.source); + next += base64VLQ.encode(sourceIdx - previousSource); + previousSource = sourceIdx; - return mappingA.name - mappingB.name; -} -exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; + // lines are stored 0-based in SourceMap spec version 3 + next += base64VLQ.encode(mapping.originalLine - 1 + - previousOriginalLine); + previousOriginalLine = mapping.originalLine - 1; -function strcmp(aStr1, aStr2) { - if (aStr1 === aStr2) { - return 0; - } + next += base64VLQ.encode(mapping.originalColumn + - previousOriginalColumn); + previousOriginalColumn = mapping.originalColumn; - if (aStr1 > aStr2) { - return 1; - } + if (mapping.name != null) { + nameIdx = this._names.indexOf(mapping.name); + next += base64VLQ.encode(nameIdx - previousName); + previousName = nameIdx; + } + } - return -1; -} + result += next; + } -/** - * Comparator between two mappings with inflated source and name strings where - * the generated positions are compared. - */ -function compareByGeneratedPositionsInflated(mappingA, mappingB) { - var cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp !== 0) { - return cmp; - } + return result; + }; - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp !== 0) { - return cmp; - } +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); + }; - cmp = strcmp(mappingA.source, mappingB.source); - if (cmp !== 0) { - return cmp; - } +/** + * 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; + } + if (this._sourceRoot != null) { + map.sourceRoot = this._sourceRoot; + } + if (this._sourcesContents) { + map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); + } - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp !== 0) { - return cmp; - } + return map; + }; - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp !== 0) { - return cmp; - } +/** + * Render the source map being generated to a string. + */ +SourceMapGenerator.prototype.toString = + function SourceMapGenerator_toString() { + return JSON.stringify(this.toJSON()); + }; - return strcmp(mappingA.name, mappingB.name); -} -exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; +exports.SourceMapGenerator = SourceMapGenerator; /***/ }), -/* 600 */ +/* 618 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -68414,4114 +71108,3968 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate * 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 util = __webpack_require__(599); -var has = Object.prototype.hasOwnProperty; -var hasNativeMap = typeof Map !== "undefined"; +var base64 = __webpack_require__(619); + +// 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; + +// binary: 011111 +var VLQ_BASE_MASK = VLQ_BASE - 1; + +// binary: 100000 +var VLQ_CONTINUATION_BIT = VLQ_BASE; /** - * 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. + * 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 ArraySet() { - this._array = []; - this._set = hasNativeMap ? new Map() : Object.create(null); +function toVLQSigned(aValue) { + return aValue < 0 + ? ((-aValue) << 1) + 1 + : (aValue << 1) + 0; } /** - * Static method for creating ArraySet instances from an existing array. + * 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 */ -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; -}; +function fromVLQSigned(aValue) { + var isNegative = (aValue & 1) === 1; + var shifted = aValue >> 1; + return isNegative + ? -shifted + : shifted; +} /** - * Return how many unique items are in this ArraySet. If duplicates have been - * added, than those do not count towards the size. - * - * @returns Number + * Returns the base 64 VLQ encoded value. */ -ArraySet.prototype.size = function ArraySet_size() { - return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length; -}; +exports.encode = function base64VLQ_encode(aValue) { + var encoded = ""; + var digit; -/** - * 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 { - this._set[sStr] = idx; + 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; } - } -}; + encoded += base64.encode(digit); + } while (vlq > 0); -/** - * Is the given string a member of this set? - * - * @param String aStr - */ -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); - } + return encoded; }; /** - * What is the index of the given string in the array? - * - * @param String aStr + * 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. */ -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]; +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."); } - } - throw new Error('"' + aStr + '" is not in the set.'); -}; + digit = base64.decode(aStr.charCodeAt(aIndex++)); + if (digit === -1) { + throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1)); + } -/** - * 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); -}; + continuation = !!(digit & VLQ_CONTINUATION_BIT); + digit &= VLQ_BASE_MASK; + result = result + (digit << shift); + shift += VLQ_BASE_SHIFT; + } while (continuation); -/** - * 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(); + aOutParam.value = fromVLQSigned(result); + aOutParam.rest = aIndex; }; -exports.ArraySet = ArraySet; - /***/ }), -/* 601 */ -/***/ (function(module, exports, __webpack_require__) { +/* 619 */ +/***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ /* - * Copyright 2014 Mozilla Foundation and contributors + * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(599); - -/** - * Determine whether mappingB is after mappingA with respect to generated - * position. - */ -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; -} - -/** - * 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 MappingList() { - this._array = []; - this._sorted = true; - // Serves as infimum - this._last = {generatedLine: -1, generatedColumn: 0}; -} - -/** - * Iterate through internal items. This method takes the same arguments that - * `Array.prototype.forEach` takes. - * - * NOTE: The order of the mappings is NOT guaranteed. - */ -MappingList.prototype.unsortedForEach = - function MappingList_forEach(aCallback, aThisArg) { - this._array.forEach(aCallback, aThisArg); - }; +var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split(''); /** - * Add the given source mapping. - * - * @param Object aMapping + * Encode an integer in the range of 0 to 63 to a single base 64 digit. */ -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); +exports.encode = function (number) { + if (0 <= number && number < intToCharMap.length) { + return intToCharMap[number]; } + throw new TypeError("Must be between 0 and 63: " + number); }; /** - * 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. + * Decode a single base 64 character code digit to an integer. Returns -1 on + * failure. */ -MappingList.prototype.toArray = function MappingList_toArray() { - if (!this._sorted) { - this._array.sort(util.compareByGeneratedPositionsInflated); - this._sorted = true; - } - return this._array; -}; - -exports.MappingList = MappingList; +exports.decode = function (charCode) { + var bigA = 65; // 'A' + var bigZ = 90; // 'Z' + var littleA = 97; // 'a' + var littleZ = 122; // 'z' -/***/ }), -/* 602 */ -/***/ (function(module, exports, __webpack_require__) { + var zero = 48; // '0' + var nine = 57; // '9' -/* -*- 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 plus = 43; // '+' + var slash = 47; // '/' -var util = __webpack_require__(599); -var binarySearch = __webpack_require__(603); -var ArraySet = __webpack_require__(600).ArraySet; -var base64VLQ = __webpack_require__(597); -var quickSort = __webpack_require__(604).quickSort; + var littleOffset = 26; + var numberOffset = 52; -function SourceMapConsumer(aSourceMap) { - var sourceMap = aSourceMap; - if (typeof aSourceMap === 'string') { - sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); + // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ + if (bigA <= charCode && charCode <= bigZ) { + return (charCode - bigA); } - return sourceMap.sections != null - ? new IndexedSourceMapConsumer(sourceMap) - : new BasicSourceMapConsumer(sourceMap); -} - -SourceMapConsumer.fromSourceMap = function(aSourceMap) { - return BasicSourceMapConsumer.fromSourceMap(aSourceMap); -} - -/** - * The version of the source mapping spec that we are consuming. - */ -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); - } + // 26 - 51: abcdefghijklmnopqrstuvwxyz + if (littleA <= charCode && charCode <= littleZ) { + return (charCode - littleA + littleOffset); + } - return this.__generatedMappings; + // 52 - 61: 0123456789 + if (zero <= charCode && charCode <= nine) { + return (charCode - zero + numberOffset); } -}); -SourceMapConsumer.prototype.__originalMappings = null; -Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { - get: function () { - if (!this.__originalMappings) { - this._parseMappings(this._mappings, this.sourceRoot); - } + // 62: + + if (charCode == plus) { + return 62; + } - return this.__originalMappings; + // 63: / + if (charCode == slash) { + return 63; } -}); -SourceMapConsumer.prototype._charIsMappingSeparator = - function SourceMapConsumer_charIsMappingSeparator(aStr, index) { - var c = aStr.charAt(index); - return c === ";" || c === ","; - }; + // Invalid base64 digit. + 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). - */ -SourceMapConsumer.prototype._parseMappings = - function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { - throw new Error("Subclasses must implement _parseMappings"); - }; -SourceMapConsumer.GENERATED_ORDER = 1; -SourceMapConsumer.ORIGINAL_ORDER = 2; +/***/ }), +/* 620 */ +/***/ (function(module, exports) { -SourceMapConsumer.GREATEST_LOWER_BOUND = 1; -SourceMapConsumer.LEAST_UPPER_BOUND = 2; +/* -*- 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 + */ /** - * Iterate over each mapping between an original source/line/column and a - * generated line/column in this source map. + * This is a helper function for getting values from parameter/options + * objects. * - * @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`. + * @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. */ -SourceMapConsumer.prototype.eachMapping = - function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { - var context = aContext || null; - var order = aOrder || SourceMapConsumer.GENERATED_ORDER; +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; - 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."); - } +var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; +var dataUrlRegexp = /^data:.+\,.+$/; - 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); +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; -/** - * 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: +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; + +/** + * 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: Optional. the column number in the original source. + * - Replaces consecutive slashes with one slash. + * - Removes unnecessary '.' parts. + * - Removes unnecessary '/..' parts. * - * and an array of objects is returned, each 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. */ -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); +function normalize(aPath) { + var path = aPath; + var url = urlParse(aPath); + if (url) { + if (!url.path) { + return aPath; } - if (!this._sources.has(needle.source)) { - return []; + 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--; + } } - needle.source = this._sources.indexOf(needle.source); + } + path = parts.join('/'); - var mappings = []; + if (path === '') { + path = isAbsolute ? '/' : '.'; + } - var index = this._findMapping(needle, - this._originalMappings, - "originalLine", - "originalColumn", - util.compareByOriginalPositions, - binarySearch.LEAST_UPPER_BOUND); - if (index >= 0) { - var mapping = this._originalMappings[index]; + if (url) { + url.path = path; + return urlGenerate(url); + } + return path; +} +exports.normalize = normalize; - if (aArgs.column === undefined) { - var originalLine = mapping.originalLine; +/** + * Joins two paths/URLs. + * + * @param aRoot The root path or URL. + * @param aPath The path or URL to be joined with the root. + * + * - 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 join(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; + } + if (aPath === "") { + aPath = "."; + } + var aPathUrl = urlParse(aPath); + var aRootUrl = urlParse(aRoot); + if (aRootUrl) { + aRoot = aRootUrl.path || '/'; + } - // 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) - }); + // `join(foo, '//www.example.org')` + if (aPathUrl && !aPathUrl.scheme) { + if (aRootUrl) { + aPathUrl.scheme = aRootUrl.scheme; + } + return urlGenerate(aPathUrl); + } - mapping = this._originalMappings[++index]; - } - } else { - var originalColumn = mapping.originalColumn; + if (aPathUrl || aPath.match(dataUrlRegexp)) { + return aPath; + } - // 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) - }); + // `join('http://', 'www.example.com')` + if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { + aRootUrl.host = aPath; + return urlGenerate(aRootUrl); + } - mapping = this._originalMappings[++index]; - } - } - } + var joined = aPath.charAt(0) === '/' + ? aPath + : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); - return mappings; - }; + if (aRootUrl) { + aRootUrl.path = joined; + return urlGenerate(aRootUrl); + } + return joined; +} +exports.join = join; -exports.SourceMapConsumer = SourceMapConsumer; +exports.isAbsolute = function (aPath) { + return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); +}; /** - * 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;" - * } + * Make a path relative to a URL or another path. * - * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# + * @param aRoot The root path or URL. + * @param aPath The path or URL to be made relative to aRoot. */ -function BasicSourceMapConsumer(aSourceMap) { - var sourceMap = aSourceMap; - if (typeof aSourceMap === 'string') { - sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); +function relative(aRoot, aPath) { + if (aRoot === "") { + aRoot = "."; } - 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); + aRoot = aRoot.replace(/\/$/, ''); - // 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); - } + // 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; + } - 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 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; + } - // 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); + ++level; + } - this.sourceRoot = sourceRoot; - this.sourcesContent = sourcesContent; - this._mappings = mappings; - this.file = file; + // 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; -BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); -BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; +var supportsNullProto = (function () { + var obj = Object.create(null); + return !('__proto__' in obj); +}()); + +function identity (s) { + return s; +} /** - * Create a BasicSourceMapConsumer from a SourceMapGenerator. + * Because behavior goes wacky when you set `__proto__` on objects, we + * have to prefix all the strings in our set with an arbitrary character. * - * @param SourceMapGenerator aSourceMap - * The source map that will be consumed. - * @returns BasicSourceMapConsumer + * See https://github.com/mozilla/source-map/pull/31 and + * https://github.com/mozilla/source-map/issues/30 + * + * @param String aStr */ -BasicSourceMapConsumer.fromSourceMap = - function SourceMapConsumer_fromSourceMap(aSourceMap) { - var smc = Object.create(BasicSourceMapConsumer.prototype); +function toSetString(aStr) { + if (isProtoString(aStr)) { + return '$' + aStr; + } - 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; + return aStr; +} +exports.toSetString = supportsNullProto ? identity : toSetString; - // 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. +function fromSetString(aStr) { + if (isProtoString(aStr)) { + return aStr.slice(1); + } - var generatedMappings = aSourceMap._mappings.toArray().slice(); - var destGeneratedMappings = smc.__generatedMappings = []; - var destOriginalMappings = smc.__originalMappings = []; + return aStr; +} +exports.fromSetString = supportsNullProto ? identity : fromSetString; - 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; +function isProtoString(s) { + if (!s) { + return false; + } - if (srcMapping.source) { - destMapping.source = sources.indexOf(srcMapping.source); - destMapping.originalLine = srcMapping.originalLine; - destMapping.originalColumn = srcMapping.originalColumn; + var length = s.length; - if (srcMapping.name) { - destMapping.name = names.indexOf(srcMapping.name); - } + if (length < 9 /* "__proto__".length */) { + return false; + } - destOriginalMappings.push(destMapping); - } + 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; + } - destGeneratedMappings.push(destMapping); + for (var i = length - 10; i >= 0; i--) { + if (s.charCodeAt(i) !== 36 /* '$' */) { + return false; } + } - quickSort(smc.__originalMappings, util.compareByOriginalPositions); - - return smc; - }; + return true; +} /** - * The version of the source mapping spec that we are consuming. + * 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. */ -BasicSourceMapConsumer.prototype._version = 3; +function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { + var cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } -/** - * 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); + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; } -}); -/** - * 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; + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0 || onlyCompareOriginal) { + return cmp; + } + + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } + + cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } + + return mappingA.name - mappingB.name; } +exports.compareByOriginalPositions = compareByOriginalPositions; /** - * 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 deflated source and name indices where + * the generated positions are compared. + * + * 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. */ -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; +function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } - while (index < length) { - if (aStr.charAt(index) === ';') { - generatedLine++; - index++; - previousGeneratedColumn = 0; - } - else if (aStr.charAt(index) === ',') { - index++; - } - else { - mapping = new Mapping(); - mapping.generatedLine = generatedLine; + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0 || onlyCompareGenerated) { + return cmp; + } - // 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); + cmp = mappingA.source - mappingB.source; + if (cmp !== 0) { + return cmp; + } - 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); - } + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } - if (segment.length === 2) { - throw new Error('Found a source, but no line and column'); - } + 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 (segment.length === 3) { - throw new Error('Found a source and line, but no column'); - } + if (aStr1 > aStr2) { + return 1; + } - cachedSegments[str] = segment; - } + return -1; +} - // Generated column. - mapping.generatedColumn = previousGeneratedColumn + segment[0]; - previousGeneratedColumn = mapping.generatedColumn; +/** + * Comparator between two mappings with inflated source and name strings where + * the generated positions are compared. + */ +function compareByGeneratedPositionsInflated(mappingA, mappingB) { + var cmp = mappingA.generatedLine - mappingB.generatedLine; + if (cmp !== 0) { + return cmp; + } - if (segment.length > 1) { - // Original source. - mapping.source = previousSource + segment[1]; - previousSource += segment[1]; + cmp = mappingA.generatedColumn - mappingB.generatedColumn; + if (cmp !== 0) { + return cmp; + } - // Original line. - mapping.originalLine = previousOriginalLine + segment[2]; - previousOriginalLine = mapping.originalLine; - // Lines are stored 0-based - mapping.originalLine += 1; + cmp = strcmp(mappingA.source, mappingB.source); + if (cmp !== 0) { + return cmp; + } - // Original column. - mapping.originalColumn = previousOriginalColumn + segment[3]; - previousOriginalColumn = mapping.originalColumn; + cmp = mappingA.originalLine - mappingB.originalLine; + if (cmp !== 0) { + return cmp; + } - if (segment.length > 4) { - // Original name. - mapping.name = previousName + segment[4]; - previousName += segment[4]; - } - } + cmp = mappingA.originalColumn - mappingB.originalColumn; + if (cmp !== 0) { + return cmp; + } - generatedMappings.push(mapping); - if (typeof mapping.originalLine === 'number') { - originalMappings.push(mapping); - } - } - } + return strcmp(mappingA.name, mappingB.name); +} +exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; - quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); - this.__generatedMappings = generatedMappings; - quickSort(originalMappings, util.compareByOriginalPositions); - this.__originalMappings = originalMappings; - }; +/***/ }), +/* 621 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Find the mapping that best matches the hypothetical "needle" mapping that - * we are searching for in the given "haystack" of mappings. +/* -*- 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 */ -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); - }; +var util = __webpack_require__(620); +var has = Object.prototype.hasOwnProperty; +var hasNativeMap = typeof Map !== "undefined"; /** - * Compute the last column for each generated mapping. The last column is - * inclusive. + * 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. */ -BasicSourceMapConsumer.prototype.computeColumnSpans = - function SourceMapConsumer_computeColumnSpans() { - for (var index = 0; index < this._generatedMappings.length; ++index) { - var mapping = this._generatedMappings[index]; +function ArraySet() { + this._array = []; + this._set = hasNativeMap ? new Map() : Object.create(null); +} - // 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]; +/** + * 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); + } + return set; +}; - if (mapping.generatedLine === nextMapping.generatedLine) { - mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1; - continue; - } - } +/** + * 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; +}; - // The last mapping for each line spans the entire line. - mapping.lastGeneratedColumn = Infinity; +/** + * 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 { + this._set[sStr] = idx; } - }; + } +}; /** - * 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: + * Is the given string a member of this set? * - * - 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 */ -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) - ); - - if (index >= 0) { - var mapping = this._generatedMappings[index]; +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); + } +}; - 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 - }; - } +/** + * 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]; } + } - return { - source: null, - line: null, - column: null, - name: null - }; - }; + throw new Error('"' + aStr + '" is not in the set.'); +}; /** - * Return true if we have the source content for every source in the source - * map, false otherwise. + * What is the element at the given index? + * + * @param Number aIdx */ -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; }); - }; +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); +}; /** - * 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. + * 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. */ -BasicSourceMapConsumer.prototype.sourceContentFor = - function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { - if (!this.sourcesContent) { - return null; - } +ArraySet.prototype.toArray = function ArraySet_toArray() { + return this._array.slice(); +}; - if (this.sourceRoot != null) { - aSource = util.relative(this.sourceRoot, aSource); - } +exports.ArraySet = ArraySet; - if (this._sources.has(aSource)) { - return this.sourcesContent[this._sources.indexOf(aSource)]; - } - 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)] - } +/***/ }), +/* 622 */ +/***/ (function(module, exports, __webpack_require__) { - if ((!url.path || url.path == "/") - && this._sources.has("/" + aSource)) { - return this.sourcesContent[this._sources.indexOf("/" + aSource)]; - } - } +/* -*- 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 + */ - // 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 util = __webpack_require__(620); /** - * 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. + * Determine whether mappingB is after mappingA with respect to generated + * position. */ -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 - }; - } - 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]; +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; +} - if (mapping.source === needle.source) { - return { - line: util.getArg(mapping, 'generatedLine', null), - column: util.getArg(mapping, 'generatedColumn', null), - lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null) - }; - } - } +/** + * 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 MappingList() { + this._array = []; + this._sorted = true; + // Serves as infimum + this._last = {generatedLine: -1, generatedColumn: 0}; +} - return { - line: null, - column: null, - lastColumn: null - }; +/** + * Iterate through internal items. This method takes the same arguments that + * `Array.prototype.forEach` takes. + * + * NOTE: The order of the mappings is NOT guaranteed. + */ +MappingList.prototype.unsortedForEach = + function MappingList_forEach(aCallback, aThisArg) { + this._array.forEach(aCallback, aThisArg); }; -exports.BasicSourceMapConsumer = BasicSourceMapConsumer; - /** - * 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. + * Add the given source mapping. * - * { - * 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 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); + } +}; + +/** + * Returns the flat, sorted array of mappings. The mappings are sorted by + * generated position. * - * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt + * 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. + */ +MappingList.prototype.toArray = function MappingList_toArray() { + if (!this._sorted) { + this._array.sort(util.compareByGeneratedPositionsInflated); + this._sorted = true; + } + return this._array; +}; + +exports.MappingList = MappingList; + + +/***/ }), +/* 623 */ +/***/ (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 */ -function IndexedSourceMapConsumer(aSourceMap) { + +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; + +function SourceMapConsumer(aSourceMap) { var sourceMap = aSourceMap; if (typeof aSourceMap === 'string') { sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); } - var version = util.getArg(sourceMap, 'version'); - var sections = util.getArg(sourceMap, 'sections'); - - if (version != this._version) { - throw new Error('Unsupported version: ' + version); - } - - this._sources = new ArraySet(); - this._names = new ArraySet(); - - 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'); - - if (offsetLine < lastOffset.line || - (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { - throw new Error('Section offsets must be ordered and non-overlapping.'); - } - 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')) - } - }); + return sourceMap.sections != null + ? new IndexedSourceMapConsumer(sourceMap) + : new BasicSourceMapConsumer(sourceMap); } -IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); -IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; +SourceMapConsumer.fromSourceMap = function(aSourceMap) { + return BasicSourceMapConsumer.fromSourceMap(aSourceMap); +} /** * The version of the source mapping spec that we are consuming. */ -IndexedSourceMapConsumer.prototype._version = 3; +SourceMapConsumer.prototype._version = 3; -/** - * The list of original sources. - */ -Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', { +// `__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 () { - 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]); - } + if (!this.__generatedMappings) { + this._parseMappings(this._mappings, this.sourceRoot); } - return sources; + + return this.__generatedMappings; } }); -/** - * 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; - } - - return (needle.generatedColumn - - section.generatedOffset.generatedColumn); - }); - var section = this._sections[sectionIndex]; - - if (!section) { - return { - source: null, - line: null, - column: null, - name: null - }; +SourceMapConsumer.prototype.__originalMappings = null; +Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { + get: function () { + if (!this.__originalMappings) { + this._parseMappings(this._mappings, this.sourceRoot); } - 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 this.__originalMappings; + } +}); + +SourceMapConsumer.prototype._charIsMappingSeparator = + function SourceMapConsumer_charIsMappingSeparator(aStr, index) { + var c = aStr.charAt(index); + return c === ";" || c === ","; }; /** - * Return true if we have the source content for every source in the source - * map, false otherwise. + * 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.hasContentsOfAllSources = - function IndexedSourceMapConsumer_hasContentsOfAllSources() { - return this._sections.every(function (s) { - return s.consumer.hasContentsOfAllSources(); - }); +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; + /** - * 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. + * Iterate over each mapping between an original source/line/column and a + * generated line/column in this source map. + * + * @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`. */ -IndexedSourceMapConsumer.prototype.sourceContentFor = - function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) { - for (var i = 0; i < this._sections.length; i++) { - var section = this._sections[i]; +SourceMapConsumer.prototype.eachMapping = + function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { + var context = aContext || null; + var order = aOrder || SourceMapConsumer.GENERATED_ORDER; - 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 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."); } + + 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); }; /** - * 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: + * 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: The column number in the original source. + * - column: Optional. the column number in the original source. * - * and an object is returned with the following properties: + * 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. */ -IndexedSourceMapConsumer.prototype.generatedPositionFor = - function IndexedSourceMapConsumer_generatedPositionFor(aArgs) { - for (var i = 0; i < this._sections.length; i++) { - var section = this._sections[i]; +SourceMapConsumer.prototype.allGeneratedPositionsFor = + function SourceMapConsumer_allGeneratedPositionsFor(aArgs) { + var line = util.getArg(aArgs, 'line'); - // 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; - } + // 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); - return { - line: null, - column: null - }; - }; + var mappings = []; -/** - * 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]; + var index = this._findMapping(needle, + this._originalMappings, + "originalLine", + "originalColumn", + util.compareByOriginalPositions, + binarySearch.LEAST_UPPER_BOUND); + if (index >= 0) { + var mapping = this._originalMappings[index]; - 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); + if (aArgs.column === undefined) { + var originalLine = mapping.originalLine; - var name = section.consumer._names.at(mapping.name); - this._names.add(name); - name = this._names.indexOf(name); + // 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) + }); - // 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 - }; + mapping = this._originalMappings[++index]; + } + } else { + var originalColumn = mapping.originalColumn; - this.__generatedMappings.push(adjustedMapping); - if (typeof adjustedMapping.originalLine === 'number') { - this.__originalMappings.push(adjustedMapping); + // 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]; } } } - quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated); - quickSort(this.__originalMappings, util.compareByOriginalPositions); + return mappings; }; -exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; - - -/***/ }), -/* 603 */ -/***/ (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 - */ - -exports.GREATEST_LOWER_BOUND = 1; -exports.LEAST_UPPER_BOUND = 2; +exports.SourceMapConsumer = SourceMapConsumer; /** - * Recursive implementation of binary search. + * 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 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); - } - - // 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); - } - - // 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; - } - } -} - -/** - * 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. + * 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: * - * @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'. + * - 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# */ -exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { - if (aHaystack.length === 0) { - return -1; +function BasicSourceMapConsumer(aSourceMap) { + var sourceMap = aSourceMap; + if (typeof aSourceMap === 'string') { + sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); } - var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, - aCompare, aBias || exports.GREATEST_LOWER_BOUND); - if (index < 0) { - return -1; - } + 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); - // 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; + // 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 index; -}; - + 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; + }); -/***/ }), -/* 604 */ -/***/ (function(module, exports) { + // 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); -/* -*- 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.sourceRoot = sourceRoot; + this.sourcesContent = sourcesContent; + this._mappings = mappings; + this.file = file; +} -// 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`. +BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer; /** - * Swap the elements indexed by `x` and `y` in the array `ary`. + * Create a BasicSourceMapConsumer from a SourceMapGenerator. * - * @param {Array} ary - * The array. - * @param {Number} x - * The index of the first item. - * @param {Number} y - * The index of the second item. + * @param SourceMapGenerator aSourceMap + * The source map that will be consumed. + * @returns BasicSourceMapConsumer */ -function swap(ary, x, y) { - var temp = ary[x]; - ary[x] = ary[y]; - ary[y] = temp; -} +BasicSourceMapConsumer.fromSourceMap = + function SourceMapConsumer_fromSourceMap(aSourceMap) { + var smc = Object.create(BasicSourceMapConsumer.prototype); -/** - * 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))); -} + 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; -/** - * 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. + // 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. - 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. + var generatedMappings = aSourceMap._mappings.toArray().slice(); + var destGeneratedMappings = smc.__generatedMappings = []; + var destOriginalMappings = smc.__originalMappings = []; - // 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; + 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; - swap(ary, pivotIndex, r); - var pivot = ary[r]; + if (srcMapping.source) { + destMapping.source = sources.indexOf(srcMapping.source); + destMapping.originalLine = srcMapping.originalLine; + destMapping.originalColumn = srcMapping.originalColumn; - // 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); + if (srcMapping.name) { + destMapping.name = names.indexOf(srcMapping.name); + } + + destOriginalMappings.push(destMapping); } - } - swap(ary, i + 1, j); - var q = i + 1; + destGeneratedMappings.push(destMapping); + } - // (2) Recurse on each half. + quickSort(smc.__originalMappings, util.compareByOriginalPositions); - doQuickSort(ary, comparator, p, q - 1); - doQuickSort(ary, comparator, q + 1, r); - } -} + return smc; + }; /** - * 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. + * The version of the source mapping spec that we are consuming. */ -exports.quickSort = function (ary, comparator) { - doQuickSort(ary, comparator, 0, ary.length - 1); -}; - - -/***/ }), -/* 605 */ -/***/ (function(module, exports, __webpack_require__) { +BasicSourceMapConsumer.prototype._version = 3; -/* -*- 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 +/** + * The list of original sources. */ - -var SourceMapGenerator = __webpack_require__(596).SourceMapGenerator; -var util = __webpack_require__(599); - -// 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)/; - -// 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$$$"; +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); + } +}); /** - * 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. + * Provide the JIT with a nice shape / hidden class. */ -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); +function Mapping() { + this.generatedLine = 0; + this.generatedColumn = 0; + this.source = null; + this.originalLine = null; + this.originalColumn = null; + this.name = null; } /** - * 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. + * 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.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; +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; - function getNextLine() { - return remainingLinesIndex < remainingLines.length ? - remainingLines[remainingLinesIndex++] : undefined; + while (index < length) { + if (aStr.charAt(index) === ';') { + generatedLine++; + index++; + previousGeneratedColumn = 0; } - }; - - // We need to remember the position of "remainingLines" - var lastGeneratedLine = 1, lastGeneratedColumn = 0; + else if (aStr.charAt(index) === ',') { + index++; + } + else { + mapping = new Mapping(); + mapping.generatedLine = generatedLine; - // 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; + // 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); - 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 + segment = cachedSegments[str]; + if (segment) { + index += str.length; } 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("")); - } + segment = []; + while (index < end) { + base64VLQ.decode(aStr, index, temp); + value = temp.value; + index = temp.rest; + segment.push(value); + } - // 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); + 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; } - node.setSourceContent(sourceFile, content); - } - }); - return node; + // Generated column. + mapping.generatedColumn = previousGeneratedColumn + segment[0]; + previousGeneratedColumn = mapping.generatedColumn; - 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)); - } - } - }; + if (segment.length > 1) { + // Original source. + mapping.source = previousSource + segment[1]; + previousSource += segment[1]; -/** - * 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; -}; + // Original line. + mapping.originalLine = previousOriginalLine + segment[2]; + previousOriginalLine = mapping.originalLine; + // Lines are stored 0-based + mapping.originalLine += 1; -/** - * Add a chunk of generated JS to the beginning of 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.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; -}; + // Original column. + mapping.originalColumn = previousOriginalColumn + segment[3]; + previousOriginalColumn = mapping.originalColumn; -/** - * 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 aFn The traversal function. - */ -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 }); + 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); + } } } - } -}; -/** - * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between - * each of `this.children`. - * - * @param aSep The separator. - */ -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; -}; + quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated); + this.__generatedMappings = generatedMappings; -/** - * 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. - */ -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; -}; + quickSort(originalMappings, util.compareByOriginalPositions); + this.__originalMappings = originalMappings; + }; /** - * 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 + * Find the mapping that best matches the hypothetical "needle" mapping that + * we are searching for in the given "haystack" of mappings. */ -SourceNode.prototype.setSourceContent = - function SourceNode_setSourceContent(aSourceFile, aSourceContent) { - this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; +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); }; /** - * 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. + * Compute the last column for each generated mapping. The last column is + * inclusive. */ -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.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; + } } - } - 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]]); + // The last mapping for each line spans the entire line. + mapping.lastGeneratedColumn = Infinity; } }; /** - * Return the string representation of this source node. Walks over the tree - * and concatenates all the various snippets together to one string. + * 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. */ -SourceNode.prototype.toString = function SourceNode_toString() { - var str = ""; - this.walk(function (chunk) { - str += chunk; - }); - return str; -}; +BasicSourceMapConsumer.prototype.originalPositionFor = + function SourceMapConsumer_originalPositionFor(aArgs) { + var needle = { + generatedLine: util.getArg(aArgs, 'line'), + generatedColumn: util.getArg(aArgs, 'column') + }; -/** - * Returns the string representation of this source node along with a source - * map. - */ -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 + var index = this._findMapping( + needle, + this._generatedMappings, + "generatedLine", + "generatedColumn", + util.compareByGeneratedPositionsDeflated, + util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND) + ); + + if (index >= 0) { + var mapping = this._generatedMappings[index]; + + 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); + } } - }); - 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 - }); + var name = util.getArg(mapping, 'name', null); + if (name !== null) { + name = this._names.at(name); } - } else { - generated.column++; + return { + source: source, + line: util.getArg(mapping, 'originalLine', null), + column: util.getArg(mapping, 'originalColumn', null), + name: name + }; } } - }); - this.walkSourceContents(function (sourceFile, sourceContent) { - map.setSourceContent(sourceFile, sourceContent); - }); - - return { code: generated.code, map: map }; -}; - -exports.SourceNode = SourceNode; - - -/***/ }), -/* 606 */ -/***/ (function(module, exports, __webpack_require__) { - -// Copyright 2014, 2015, 2016, 2017 Simon Lydell -// X11 (“MIT”) Licensed. (See LICENSE.) - -var sourceMappingURL = __webpack_require__(607) -var resolveUrl = __webpack_require__(608) -var decodeUriComponent = __webpack_require__(609) -var urix = __webpack_require__(611) -var atob = __webpack_require__(612) + 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; }); + }; -function callbackAsync(callback, error, result) { - setImmediate(function() { callback(error, result) }) -} +/** + * 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 parseMapToJSON(string, data) { - try { - return JSON.parse(string.replace(/^\)\]\}'/, "")) - } catch (error) { - error.sourceMapData = data - throw error - } -} + if (this.sourceRoot != null) { + aSource = util.relative(this.sourceRoot, aSource); + } -function readSync(read, url, data) { - var readUrl = decodeUriComponent(url) - try { - return String(read(readUrl)) - } catch (error) { - error.sourceMapData = data - throw error - } -} + if (this._sources.has(aSource)) { + return this.sourcesContent[this._sources.indexOf(aSource)]; + } + 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)]; + } + } -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) + // 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; } - mapData.map = String(result) - try { - mapData.map = parseMapToJSON(mapData.map, mapData) - } catch (error) { - return callback(error) + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); } - 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 -} +/** + * 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); + } + if (!this._sources.has(source)) { + return { + line: null, + column: null, + lastColumn: null + }; + } + 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 + }; + }; + +exports.BasicSourceMapConsumer = BasicSourceMapConsumer; + +/** + * 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(/^\)\]\}'/, '')); } -} - + var version = util.getArg(sourceMap, 'version'); + var sections = util.getArg(sourceMap, 'sections'); -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 (version != this._version) { + throw new Error('Unsupported version: ' + version); } - if (pending === 0) { - callbackAsync(callback, null, result) - return - } + this._sources = new ArraySet(); + this._names = new ArraySet(); - var done = function() { - pending-- - if (pending === 0) { - callback(null, result) + 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'); - 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() - }) + if (offsetLine < lastOffset.line || + (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) { + throw new Error('Section offsets must be ordered and non-overlapping.'); } - }) + 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')) + } + }); } -function resolveSourcesSync(map, mapUrl, read, options) { - var result = { - sourcesResolved: [], - sourcesContent: [] - } +IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype); +IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer; - if (!map.sources || map.sources.length === 0) { - return result - } +/** + * The version of the source mapping spec that we are consuming. + */ +IndexedSourceMapConsumer.prototype._version = 3; - 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 - } +/** + * 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]); } } - }) + return sources; + } +}); - return result -} +/** + * 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') + }; -var endingSlash = /\/?$/ + // 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; + } -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]) + return (needle.generatedColumn - + section.generatedOffset.generatedColumn); + }); + var section = this._sections[sectionIndex]; + + if (!section) { + return { + source: null, + line: null, + column: null, + name: null + }; } - sourceContent = (map.sourcesContent || [])[index] - fn(fullUrl, sourceContent, index) - } -} + 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 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(); + }); + }; -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) - }) - } +/** + * 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]; - function _resolveSources(mapData) { - resolveSources(mapData.map, mapData.sourcesRelativeTo, read, options, function(error, result) { - if (error) { - return callback(error) + var content = section.consumer.sourceContentFor(aSource, true); + if (content) { + return content; } - 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 + if (nullOnMissing) { + return null; } - } - var result = resolveSourcesSync(mapData.map, mapData.sourcesRelativeTo, read, options) - mapData.sourcesResolved = result.sourcesResolved - mapData.sourcesContent = result.sourcesContent - return mapData -} - - - -module.exports = { - resolveSourceMap: resolveSourceMap, - resolveSourceMapSync: resolveSourceMapSync, - resolveSources: resolveSources, - resolveSourcesSync: resolveSourcesSync, - resolve: resolve, - resolveSync: resolveSync, - parseMapToJSON: parseMapToJSON -} - - -/***/ }), -/* 607 */ -/***/ (function(module, exports, __webpack_require__) { - -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() { + else { + throw new Error('"' + aSource + '" is not in the SourceMap.'); + } + }; - var innerRegex = /[#@] sourceMappingURL=([^\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]; - var regex = RegExp( - "(?:" + - "/\\*" + - "(?:\\s*\r?\n(?://)?)?" + - "(?:" + innerRegex.source + ")" + - "\\s*" + - "\\*/" + - "|" + - "//(?:" + innerRegex.source + ")" + - ")" + - "\\s*" - ) + // 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 { + 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); + } } } - } - -})); - -/***/ }), -/* 608 */ -/***/ (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 + */ -/***/ }), -/* 609 */ -/***/ (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__(610) + // 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; + } -/***/ }), -/* 610 */ -/***/ (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); }; /***/ }), -/* 611 */ +/* 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); -/***/ }), -/* 612 */ -/***/ (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; -/***/ }), -/* 613 */ -/***/ (function(module, exports, __webpack_require__) { + function getNextLine() { + return remainingLinesIndex < remainingLines.length ? + remainingLines[remainingLinesIndex++] : undefined; + } + }; -"use strict"; + // We need to remember the position of "remainingLines" + var lastGeneratedLine = 1, lastGeneratedColumn = 0; + // 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; -var fs = __webpack_require__(133); -var path = __webpack_require__(4); -var define = __webpack_require__(517); -var utils = __webpack_require__(594); + 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("")); + } -/** - * 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 - */ + // 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); + } + }); -module.exports = mixin; + return node; + + 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. */ +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; +}; -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; +/** + * 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 aFn The traversal function. + */ +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 }); + } + } + } }; /** - * Emit `str` with `position`. + * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between + * each of `this.children`. * - * @param {String} str - * @param {Object} [pos] - * @return {String} + * @param aSep The separator. */ - -exports.emit = function(str, node) { - var position = node.position || {}; - var source = position.source; - if (source) { - if (position.filepath) { - source = utils.unixify(position.filepath); - } - - 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 (position.content) { - this.addContent(source, position); - } - if (position.filepath) { - this.addFile(source, position); +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); } - - this.updatePosition(str); - this.output += str; + newChildren.push(this.children[i]); + this.children = newChildren; } - return str; + return this; }; /** - * Adds a file to the source map output if it has not already been added - * @param {String} `file` - * @param {Object} `pos` + * 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.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.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; }; /** - * Adds a content source to the source map output if it has not already been added - * @param {String} `source` - * @param {Object} `position` + * 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.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.setSourceContent = + function SourceNode_setSourceContent(aSourceFile, aSourceContent) { + this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; + }; /** - * Applies any original source maps to the output and embeds the source file - * contents in the source map. + * 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. */ - -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))); +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); } } - }, this); + + 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]]); + } + }; + +/** + * Return the string representation of this source node. Walks over the tree + * and concatenates all the various snippets together to one string. + */ +SourceNode.prototype.toString = function SourceNode_toString() { + var str = ""; + this.walk(function (chunk) { + str += chunk; + }); + return str; }; /** - * Process comments, drops sourceMap comments. - * @param {Object} node + * Returns the string representation of this source node along with a source + * map. */ +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 + }); + } + } else { + generated.column++; + } + } + }); + this.walkSourceContents(function (sourceFile, sourceContent) { + map.setSourceContent(sourceFile, sourceContent); + }); -exports.comment = function(node) { - if (/^# sourceMappingURL=/.test(node.comment)) { - return this.emit('', node.position); - } - return this._comment(node); + return { code: generated.code, map: map }; }; +exports.SourceNode = SourceNode; + /***/ }), -/* 614 */ +/* 627 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; +// Copyright 2014, 2015, 2016, 2017 Simon Lydell +// X11 (“MIT”) Licensed. (See LICENSE.) +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) -var use = __webpack_require__(586); -var util = __webpack_require__(111); -var Cache = __webpack_require__(615); -var define = __webpack_require__(517); -var debug = __webpack_require__(588)('snapdragon:parser'); -var Position = __webpack_require__(616); -var utils = __webpack_require__(594); -/** - * Create a new `Parser` with the given `input` and `options`. - * @param {String} `input` - * @param {Object} `options` - * @api public - */ -function Parser(options) { - debug('initializing', __filename); - this.options = utils.extend({source: 'string'}, options); - this.init(this.options); - use(this); +function callbackAsync(callback, error, result) { + setImmediate(function() { callback(error, result) }) } -/** - * Prototype methods - */ +function parseMapToJSON(string, data) { + try { + return JSON.parse(string.replace(/^\)\]\}'/, "")) + } catch (error) { + error.sourceMapData = data + throw error + } +} -Parser.prototype = { - constructor: Parser, +function readSync(read, url, data) { + var readUrl = decodeUriComponent(url) + try { + return String(read(readUrl)) + } catch (error) { + error.sourceMapData = data + throw error + } +} - 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'; +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) + }) +} - var pos = this.position(); - this.bos = pos({type: 'bos', val: ''}); +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 +} - this.ast = { - type: 'root', - errors: this.errors, - nodes: [this.bos] - }; +var dataUriRegex = /^data:([^,;]*)(;[^,;]*)*(?:,(.*))?$/ +var jsonMimeTypeRegex = /^(?:application|text)\/json$/ - define(this.bos, 'parent', this.ast); - this.nodes = [this.ast]; +function resolveSourceMapHelper(code, codeUrl) { + codeUrl = urix(codeUrl) - this.count = 0; - this.setCount = 0; - this.stack = []; - }, + var url = sourceMappingURL.getFrom(code) + if (!url) { + return null + } - /** - * Throw a formatted error with the cursor column and `msg`. - * @param {String} `msg` Message to use in the Error. - */ + 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 + } - 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 mapUrl = resolveUrl(codeUrl, url) + return { + sourceMappingURL: url, + url: mapUrl, + sourcesRelativeTo: mapUrl, + map: null + } +} - 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; - } - }, - /** - * 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 - */ +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: [] + } - define: function(key, val) { - define(this, key, val); - return this; - }, + if (pending === 0) { + callbackAsync(callback, null, result) + return + } - /** - * Mark position and patch `node.position`. - */ + var done = function() { + pending-- + if (pending === 0) { + callback(null, result) + } + } - position: function() { - var start = { line: this.line, column: this.column }; - var self = this; + 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() + }) + } + }) +} - return function(node) { - define(node, 'position', new Position(start, self)); - return node; - }; - }, +function resolveSourcesSync(map, mapUrl, read, options) { + var result = { + sourcesResolved: [], + sourcesContent: [] + } - /** - * Set parser `name` with the given `fn` - * @param {String} `name` - * @param {Function} `fn` - * @api public - */ + if (!map.sources || map.sources.length === 0) { + return result + } - set: function(type, fn) { - if (this.types.indexOf(type) === -1) { - this.types.push(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.parsers[type] = fn.bind(this); - return this; - }, + }) - /** - * Get parser `name` - * @param {String} `name` - * @api public - */ + return result +} - get: function(name) { - return this.parsers[name]; - }, +var endingSlash = /\/?$/ - /** - * Push a `token` onto the `type` stack. - * - * @param {String} `type` - * @return {Object} `token` - * @api public - */ +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) + } +} - 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(); - }, +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) + }) + } - /** - * Return true if inside a `stack` node. Types are `braces`, `parens` or `brackets`. - * - * @param {String} `type` - * @return {Boolean} - * @api public - */ + 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) + }) + } +} - isInside: function(type) { - this.sets[type] = this.sets[type] || []; - return this.sets[type].length > 0; - }, +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 +} - /** - * 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; - }, - /** - * Get the previous AST node - * @return {Object} - */ +module.exports = { + resolveSourceMap: resolveSourceMap, + resolveSourceMapSync: resolveSourceMapSync, + resolveSources: resolveSources, + resolveSourcesSync: resolveSourcesSync, + resolve: resolve, + resolveSync: resolveSync, + parseMapToJSON: parseMapToJSON +} - prev: function(n) { - return this.stack.length > 0 - ? utils.last(this.stack, n) - : utils.last(this.nodes, n); - }, - /** - * Update line and column based on `str`. - */ +/***/ }), +/* 628 */ +/***/ (function(module, exports, __webpack_require__) { - consume: function(len) { - this.input = this.input.substr(len); - }, +var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell +// X11 (“MIT”) Licensed. (See LICENSE.) - /** - * Update column based on `str`. - */ +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() { - 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); - }, + var innerRegex = /[#@] sourceMappingURL=([^\s'"]*)/ - /** - * Match `regex`, return captures, and update the cursor position by `match[0]` length. - * @param {RegExp} `regex` - * @return {Object} - */ + var regex = RegExp( + "(?:" + + "/\\*" + + "(?:\\s*\r?\n(?://)?)?" + + "(?:" + innerRegex.source + ")" + + "\\s*" + + "\\*/" + + "|" + + "//(?:" + innerRegex.source + ")" + + ")" + + "\\s*" + ) - match: function(regex) { - var m = regex.exec(this.input); - if (m) { - this.updatePosition(m[0], m[0].length); - return m; - } - }, + return { - /** - * Capture `type` with the given regex. - * @param {String} `type` - * @param {RegExp} `regex` - * @return {Function} - */ + regex: regex, + _innerRegex: innerRegex, - capture: function(type, regex) { - if (typeof regex === 'function') { - return this.set.apply(this, arguments); - } + getFrom: function(code) { + var match = code.match(regex) + return (match ? match[1] || match[2] || "" : null) + }, - 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; + existsIn: function(code) { + return regex.test(code) + }, - var prev = this.prev(); - var node = pos({ - type: type, - val: m[0], - parsed: parsed, - rest: this.input - }); + removeFrom: function(code) { + return code.replace(regex, "") + }, - if (m[1]) { - node.inner = m[1]; + 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 } + } + } - 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 - */ - - capturePair: function(type, openRegex, closeRegex, fn) { - this.sets[type] = this.sets[type] || []; - - /** - * Open - */ +})); - this.set(type + '.open', function() { - var parsed = this.parsed; - var pos = this.position(); - var m = this.match(openRegex); - if (!m || !m[0]) return; - var val = m[0]; - this.setCount++; - this.specialChars = true; - var open = pos({ - type: type + '.open', - val: val, - rest: this.input - }); +/***/ }), +/* 629 */ +/***/ (function(module, exports, __webpack_require__) { - if (typeof m[1] !== 'undefined') { - open.inner = m[1]; - } +// Copyright 2014 Simon Lydell +// X11 (“MIT”) Licensed. (See LICENSE.) - var prev = this.prev(); - var node = pos({ - type: type, - nodes: [open] - }); +var url = __webpack_require__(197) - define(node, 'rest', this.input); - define(node, 'parsed', parsed); - define(node, 'prefix', m[1]); - define(node, 'parent', prev); - define(open, 'parent', node); +function resolveUrl(/* ...urls */) { + return Array.prototype.reduce.call(arguments, function(resolved, nextUrl) { + return url.resolve(resolved, nextUrl) + }) +} - if (typeof fn === 'function') { - fn.call(this, open, node); - } +module.exports = resolveUrl - this.push(type, node); - prev.nodes.push(node); - }); - /** - * Close - */ +/***/ }), +/* 630 */ +/***/ (function(module, exports, __webpack_require__) { - this.set(type + '.close', function() { - var pos = this.position(); - var m = this.match(closeRegex); - if (!m || !m[0]) return; +// Copyright 2017 Simon Lydell +// X11 (“MIT”) Licensed. (See LICENSE.) - var parent = this.pop(type); - var node = pos({ - type: type + '.close', - rest: this.input, - suffix: m[1], - val: m[0] - }); +var decodeUriComponent = __webpack_require__(631) - if (!this.isType(parent, type)) { - if (this.options.strict) { - throw new Error('missing opening "' + type + '"'); - } +function customDecodeUriComponent(string) { + // `decodeUriComponent` turns `+` into ` `, but that's not wanted. + return decodeUriComponent(string.replace(/\+/g, "%2B")) +} - this.setCount--; - node.escaped = true; - return node; - } +module.exports = customDecodeUriComponent - if (node.suffix === '\\') { - parent.escaped = true; - node.escaped = true; - } - parent.nodes.push(node); - define(node, 'parent', parent); - }); +/***/ }), +/* 631 */ +/***/ (function(module, exports, __webpack_require__) { - return this; - }, +"use strict"; - /** - * Capture end-of-string - */ +var token = '%[a-f0-9]{2}'; +var singleMatcher = new RegExp(token, 'gi'); +var multiMatcher = new RegExp('(' + token + ')+', 'gi'); - eos: function() { - var pos = this.position(); - if (this.input) return; - var prev = this.prev(); +function decodeComponents(components, split) { + try { + // Try to decode the entire string first + return decodeURIComponent(components.join('')); + } catch (err) { + // Do nothing + } - while (prev.type !== 'root' && !prev.visited) { - if (this.options.strict === true) { - throw new SyntaxError('invalid syntax:' + util.inspect(prev, null, 2)); - } + if (components.length === 1) { + return components; + } - if (!hasDelims(prev)) { - prev.parent.escaped = true; - prev.escaped = true; - } + split = split || 1; - visit(prev, function(node) { - if (!hasDelims(node.parent)) { - node.parent.escaped = true; - node.escaped = true; - } - }); + // Split the array in 2 parts + var left = components.slice(0, split); + var right = components.slice(split); - prev = prev.parent; - } + return Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right)); +} - var tok = pos({ - type: 'eos', - val: this.append || '' - }); +function decode(input) { + try { + return decodeURIComponent(input); + } catch (err) { + var tokens = input.match(singleMatcher); - define(tok, 'parent', this.ast); - return tok; - }, + for (var i = 1; i < tokens.length; i++) { + input = decodeComponents(tokens, i).join(''); - /** - * Run parsers to advance the cursor position - */ + tokens = input.match(singleMatcher); + } - next: function() { - var parsed = this.parsed; - var len = this.types.length; - var idx = -1; - var tok; + return input; + } +} - 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; - } - } - }, +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' + }; - /** - * Parse the given string. - * @return {Array} - */ + 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]); - parse: function(input) { - if (typeof input !== 'string') { - throw new TypeError('expected a string'); - } + if (result !== match[0]) { + replaceMap[match[0]] = result; + } + } - this.init(this.options); - this.orig = input; - this.input = input; - var self = this; + match = multiMatcher.exec(input); + } - function parse() { - // check input before calling `.next()` - input = self.input; + // Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else + replaceMap['%C2'] = '\uFFFD'; - // 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); - } - } + var entries = Object.keys(replaceMap); - if (self.sets.hasOwnProperty(prev.type)) { - self.currentType = prev.type; - } - } + 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]); + } - // 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) + '"'); - } - } + return input; +} - 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 + '"'); - } +module.exports = function (encodedURI) { + if (typeof encodedURI !== 'string') { + throw new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`'); + } - var eos = this.eos(); - var tok = this.prev(); - if (tok.type !== 'eos') { - this.ast.nodes.push(eos); - } + try { + encodedURI = encodedURI.replace(/\+/g, ' '); - return this.ast; - } + // Try the built in decoder first + return decodeURIComponent(encodedURI); + } catch (err) { + // Fallback to a more advanced decoder + return customDecodeURIComponent(encodedURI); + } }; -/** - * 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; -} +/***/ }), +/* 632 */ +/***/ (function(module, exports, __webpack_require__) { -/** - * Map visit over array of `nodes`. - */ +// 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 -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'); -} +/***/ }), +/* 633 */ +/***/ (function(module, exports, __webpack_require__) { -function hasClose(node) { - return node.nodes && utils.last(node.nodes).type === (node.type + '.close'); -} +"use strict"; -function hasDelims(node) { - return hasOpen(node) && hasClose(node); -} -/** - * Expose `Parser` - */ +function atob(str) { + return Buffer.from(str, 'base64').toString('binary'); +} -module.exports = Parser; +module.exports = atob.atob = atob; /***/ }), -/* 615 */ +/* 634 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -/*! - * map-cache - * - * Copyright (c) 2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - -var hasOwn = Object.prototype.hasOwnProperty; +var fs = __webpack_require__(134); +var path = __webpack_require__(4); +var define = __webpack_require__(596); +var utils = __webpack_require__(615); /** - * Expose `MapCache` + * 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 */ -module.exports = MapCache; +module.exports = mixin; /** - * Creates a cache object to store key/value pairs. - * - * ```js - * var cache = new MapCache(); - * ``` + * Mixin source map support into `compiler`. * + * @param {Object} `compiler` * @api public */ -function MapCache(data) { - this.__data__ = data || {}; +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]); + } } /** - * Adds `value` to `key` on the cache. - * - * ```js - * cache.set('foo', 'bar'); - * ``` + * Update position. * - * @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 + * @param {String} str */ -MapCache.prototype.set = function mapSet(key, value) { - if (key !== '__proto__') { - this.__data__[key] = value; - } - return this; +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; }; /** - * Gets the cached value for `key`. - * - * ```js - * cache.get('foo'); - * //=> 'bar' - * ``` + * Emit `str` with `position`. * - * @param {String} `key` The key of the value to get. - * @returns {*} Returns the cached value. - * @api public + * @param {String} str + * @param {Object} [pos] + * @return {String} */ -MapCache.prototype.get = function mapGet(key) { - return key === '__proto__' ? undefined : this.__data__[key]; +exports.emit = function(str, node) { + var position = node.position || {}; + var source = position.source; + if (source) { + if (position.filepath) { + source = utils.unixify(position.filepath); + } + + 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 (position.content) { + this.addContent(source, position); + } + if (position.filepath) { + this.addFile(source, position); + } + + this.updatePosition(str); + this.output += str; + } + return str; }; /** - * 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 + * Adds a file to the source map output if it has not already been added + * @param {String} `file` + * @param {Object} `pos` */ -MapCache.prototype.has = function mapHas(key) { - return key !== '__proto__' && hasOwn.call(this.__data__, key); +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; }; /** - * 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 + * Adds a content source to the source map output if it has not already been added + * @param {String} `source` + * @param {Object} `position` */ -MapCache.prototype.del = function mapDelete(key) { - return this.has(key) && delete this.__data__[key]; +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); }; +/** + * Applies any original source maps to the output and embeds the source file + * contents in the source map. + */ -/***/ }), -/* 616 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - +exports.applySourceMaps = function() { + Object.keys(this.files).forEach(function(file) { + var content = this.files[file]; + this.map.setSourceContent(file, content); -var define = __webpack_require__(517); + 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); +}; /** - * Store position for a node + * Process comments, drops sourceMap comments. + * @param {Object} node */ -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); +exports.comment = function(node) { + if (/^# sourceMappingURL=/.test(node.comment)) { + return this.emit('', node.position); + } + return this._comment(node); }; /***/ }), -/* 617 */ +/* 635 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var safe = __webpack_require__(618); -var define = __webpack_require__(624); -var extend = __webpack_require__(625); -var not = __webpack_require__(627); -var MAX_LENGTH = 1024 * 64; - -/** - * Session cache - */ - -var cache = {}; +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 regular expression from the given `pattern` string. - * - * @param {String|RegExp} `pattern` Pattern can be a string or regular expression. + * Create a new `Parser` with the given `input` and `options`. + * @param {String} `input` * @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); -}; +function Parser(options) { + debug('initializing', __filename); + this.options = utils.extend({source: 'string'}, options); + this.init(this.options); + use(this); +} /** - * 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 + * Prototype methods */ -function makeRe(pattern, options) { - if (pattern instanceof RegExp) { - return pattern; - } - - if (typeof pattern !== 'string') { - throw new TypeError('expected a string'); - } +Parser.prototype = { + constructor: Parser, - if (pattern.length > MAX_LENGTH) { - throw new Error('expected pattern to be less than ' + MAX_LENGTH + ' characters'); - } + init: function(options) { + this.orig = ''; + this.input = ''; + this.parsed = ''; - var key = pattern; - // do this before shallow cloning options, it's a lot faster - if (!options || (options && options.cache !== false)) { - key = createKey(pattern, options); + this.column = 1; + this.line = 1; - if (cache.hasOwnProperty(key)) { - return cache[key]; - } - } + 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 opts = extend({}, options); - if (opts.contains === true) { - if (opts.negate === true) { - opts.strictNegate = false; - } else { - opts.strict = false; - } - } + var pos = this.position(); + this.bos = pos({type: 'bos', val: ''}); - if (opts.strict === false) { - opts.strictOpen = false; - opts.strictClose = false; - } + this.ast = { + type: 'root', + errors: this.errors, + nodes: [this.bos] + }; - var open = opts.strictOpen !== false ? '^' : ''; - var close = opts.strictClose !== false ? '$' : ''; - var flags = opts.flags || ''; - var regex; + define(this.bos, 'parent', this.ast); + this.nodes = [this.ast]; - if (opts.nocase === true && !/i/.test(flags)) { - flags += 'i'; - } + this.count = 0; + this.setCount = 0; + this.stack = []; + }, - try { - if (opts.negate || typeof opts.strictNegate === 'boolean') { - pattern = not.create(pattern, opts); - } + /** + * Throw a formatted error with the cursor column and `msg`. + * @param {String} `msg` Message to use in the Error. + */ - var str = open + '(?:' + pattern + ')' + close; - regex = new RegExp(str, flags); + 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; - if (opts.safe === true && safe(regex) === false) { - throw new Error('potentially unsafe regular expression: ' + regex.source); - } + var message = source + ' : ' + msg; + var err = new Error(message); + err.source = source; + err.reason = msg; + err.pos = pos; - } catch (err) { - if (opts.strictErrors === true || opts.safe === true) { - err.key = key; - err.pattern = pattern; - err.originalOptions = options; - err.createdOptions = opts; + if (this.options.silent) { + this.errors.push(err); + } else { throw err; } + }, - try { - regex = new RegExp('^' + pattern.replace(/(\W)/g, '\\$1') + '$'); - } catch (err) { - regex = /.^/; //<= match nothing - } - } - - if (opts.cache !== false) { - memoize(regex, key, pattern, opts); - } - return regex; -} - -/** - * 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 memoize(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; - - -/***/ }), -/* 618 */ -/***/ (function(module, exports, __webpack_require__) { - -var parse = __webpack_require__(619); -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]'; -} - - -/***/ }), -/* 619 */ -/***/ (function(module, exports, __webpack_require__) { - -var util = __webpack_require__(620); -var types = __webpack_require__(621); -var sets = __webpack_require__(622); -var positions = __webpack_require__(623); - - -module.exports = function(regexpStr) { - var i = 0, l, c, - start = { type: types.ROOT, stack: []}, - - // Keep track of last clause/group and stack. - lastGroup = start, - last = start.stack, - groupStack = []; - - - var repeatErr = function(i) { - util.error(regexpStr, 'Nothing to repeat at column ' + (i - 1)); - }; - - // Decode a few escaped characters. - var str = util.strToChars(regexpStr); - l = str.length; - - // Iterate through each character in string. - while (i < l) { - c = str[i++]; - - switch (c) { - // Handle escaped characters, inclues a few sets. - case '\\': - c = str[i++]; + /** + * 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 + */ - switch (c) { - case 'b': - last.push(positions.wordBoundary()); - break; + define: function(key, val) { + define(this, key, val); + return this; + }, - case 'B': - last.push(positions.nonWordBoundary()); - break; + /** + * Mark position and patch `node.position`. + */ - case 'w': - last.push(sets.words()); - break; + position: function() { + var start = { line: this.line, column: this.column }; + var self = this; - case 'W': - last.push(sets.notWords()); - break; + return function(node) { + define(node, 'position', new Position(start, self)); + return node; + }; + }, - case 'd': - last.push(sets.ints()); - break; + /** + * Set parser `name` with the given `fn` + * @param {String} `name` + * @param {Function} `fn` + * @api public + */ - case 'D': - last.push(sets.notInts()); - break; + set: function(type, fn) { + if (this.types.indexOf(type) === -1) { + this.types.push(type); + } + this.parsers[type] = fn.bind(this); + return this; + }, - case 's': - last.push(sets.whitespace()); - break; + /** + * Get parser `name` + * @param {String} `name` + * @api public + */ - case 'S': - last.push(sets.notWhitespace()); - break; + get: function(name) { + return this.parsers[name]; + }, - 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) }); + /** + * Push a `token` onto the `type` stack. + * + * @param {String} `type` + * @return {Object} `token` + * @api public + */ - // Escaped character. - } else { - last.push({ type: types.CHAR, value: c.charCodeAt(0) }); - } - } + 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(); + }, - // Positionals. - case '^': - last.push(positions.begin()); - break; + /** + * Return true if inside a `stack` node. Types are `braces`, `parens` or `brackets`. + * + * @param {String} `type` + * @return {Boolean} + * @api public + */ - case '$': - last.push(positions.end()); - break; + isInside: function(type) { + this.sets[type] = this.sets[type] || []; + return this.sets[type].length > 0; + }, + /** + * Return true if `node` is the given `type`. + * + * ```js + * parser.isType(node, 'brace'); + * ``` + * @param {Object} `node` + * @param {String} `type` + * @return {Boolean} + * @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; - } + isType: function(node, type) { + return node && node.type === type; + }, - // Get all the characters in class. - var classTokens = util.tokenizeClass(str.slice(i), regexpStr); + /** + * Get the previous AST node + * @return {Object} + */ - // Increase index by length of class. - i += classTokens[1]; - last.push({ - type: types.SET, - set: classTokens[0], - not: not, - }); + prev: function(n) { + return this.stack.length > 0 + ? utils.last(this.stack, n) + : utils.last(this.nodes, n); + }, - break; + /** + * Update line and column based on `str`. + */ + consume: function(len) { + this.input = this.input.substr(len); + }, - // Class of any character except \n. - case '.': - last.push(sets.anyChar()); - break; + /** + * Update column based on `str`. + */ + 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); + }, - // Push group onto stack. - case '(': - // Create group. - var group = { - type: types.GROUP, - stack: [], - remember: true, - }; + /** + * Match `regex`, return captures, and update the cursor position by `match[0]` length. + * @param {RegExp} `regex` + * @return {Object} + */ - c = str[i]; + match: function(regex) { + var m = regex.exec(this.input); + if (m) { + this.updatePosition(m[0], m[0].length); + return m; + } + }, - // If if this is a special kind of group. - if (c === '?') { - c = str[i + 1]; - i += 2; + /** + * Capture `type` with the given regex. + * @param {String} `type` + * @param {RegExp} `regex` + * @return {Function} + */ - // Match if followed by. - if (c === '=') { - group.followedBy = true; + capture: function(type, regex) { + if (typeof regex === 'function') { + return this.set.apply(this, arguments); + } - // Match if not followed by. - } else if (c === '!') { - group.notFollowedBy = true; + 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; - } else if (c !== ':') { - util.error(regexpStr, - 'Invalid group, character \'' + c + - '\' after \'?\' at column ' + (i - 1)); - } + var prev = this.prev(); + var node = pos({ + type: type, + val: m[0], + parsed: parsed, + rest: this.input + }); - group.remember = false; - } + if (m[1]) { + node.inner = m[1]; + } - // Insert subgroup into current group stack. - last.push(group); + define(node, 'inside', this.stack.length > 0); + define(node, 'parent', prev); + prev.nodes.push(node); + }.bind(this)); + return this; + }, - // Remember the current group for when the group closes. - groupStack.push(lastGroup); + /** + * Create a parser with open and close for parens, + * brackets or braces + */ - // Make this new group the current group. - lastGroup = group; - last = group.stack; - break; + capturePair: function(type, openRegex, closeRegex, fn) { + this.sets[type] = this.sets[type] || []; + /** + * Open + */ - // Pop group out of stack. - case ')': - if (groupStack.length === 0) { - util.error(regexpStr, 'Unmatched ) at column ' + (i - 1)); - } - lastGroup = groupStack.pop(); + this.set(type + '.open', function() { + var parsed = this.parsed; + var pos = this.position(); + var m = this.match(openRegex); + if (!m || !m[0]) return; - // 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; + var val = m[0]; + this.setCount++; + this.specialChars = true; + var open = pos({ + type: type + '.open', + val: val, + rest: this.input + }); + if (typeof m[1] !== 'undefined') { + open.inner = m[1]; + } - // 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; - } + var prev = this.prev(); + var node = pos({ + type: type, + nodes: [open] + }); - // Create a new stack and add to options for rest of clause. - var stack = []; - lastGroup.options.push(stack); - last = stack; - break; + 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); + } - // 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; + this.push(type, node); + prev.nodes.push(node); + }); - last.push({ - type: types.REPETITION, - min: min, - max: max, - value: last.pop(), - }); - } else { - last.push({ - type: types.CHAR, - value: 123, - }); - } - break; + /** + * Close + */ - case '?': - if (last.length === 0) { - repeatErr(i); - } - last.push({ - type: types.REPETITION, - min: 0, - max: 1, - value: last.pop(), - }); - break; + this.set(type + '.close', function() { + var pos = this.position(); + var m = this.match(closeRegex); + 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 parent = this.pop(type); + var node = pos({ + type: type + '.close', + rest: this.input, + suffix: m[1], + val: m[0] + }); - case '*': - if (last.length === 0) { - repeatErr(i); + if (!this.isType(parent, type)) { + if (this.options.strict) { + throw new Error('missing opening "' + type + '"'); } - 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), - }); - } + this.setCount--; + node.escaped = true; + return node; + } - } + if (node.suffix === '\\') { + parent.escaped = true; + node.escaped = true; + } - // Check if any groups have not been closed. - if (groupStack.length !== 0) { - util.error(regexpStr, 'Unterminated group'); - } + parent.nodes.push(node); + define(node, 'parent', parent); + }); - return start; -}; + return this; + }, -module.exports.types = types; + /** + * Capture end-of-string + */ + eos: function() { + var pos = this.position(); + if (this.input) return; + var prev = this.prev(); -/***/ }), -/* 620 */ -/***/ (function(module, exports, __webpack_require__) { + while (prev.type !== 'root' && !prev.visited) { + if (this.options.strict === true) { + throw new SyntaxError('invalid syntax:' + util.inspect(prev, null, 2)); + } -var types = __webpack_require__(621); -var sets = __webpack_require__(622); + 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; + } + }); -// All of these are private and only used by randexp. -// It's assumed that they will always be called with the correct input. + prev = prev.parent; + } -var CTRL = '@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^ ?'; -var SLSH = { '0': 0, 't': 9, 'n': 10, 'v': 11, 'f': 12, 'r': 13 }; + var tok = pos({ + type: 'eos', + val: this.append || '' + }); -/** - * 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; - } + define(tok, 'parent', this.ast); + return tok; + }, - var code = b ? 8 : - a16 ? parseInt(a16, 16) : - b16 ? parseInt(b16, 16) : - c8 ? parseInt(c8, 8) : - dctrl ? CTRL.indexOf(dctrl) : - SLSH[eslsh]; + /** + * Run parsers to advance the cursor position + */ - var c = String.fromCharCode(code); + next: function() { + var parsed = this.parsed; + var len = this.types.length; + var idx = -1; + var tok; - // Escape special regex characters. - if (/[\[\]{}\^$.|?*+()]/.test(c)) { - c = '\\' + c; + 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; + } } + }, - return c; - }); + /** + * Parse the given string. + * @return {Array} + */ - return str; -}; + parse: function(input) { + if (typeof input !== 'string') { + throw new TypeError('expected a string'); + } + this.init(this.options); + this.orig = input; + this.input = input; + var self = this; -/** - * 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; + function parse() { + // check input before calling `.next()` + input = self.input; + // 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); + } + } - while ((rs = regexp.exec(str)) != null) { - if (rs[1]) { - tokens.push(sets.words()); + if (self.sets.hasOwnProperty(prev.type)) { + self.currentType = prev.type; + } + } - } else if (rs[2]) { - tokens.push(sets.ints()); + // 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 (rs[3]) { - tokens.push(sets.whitespace()); + 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 if (rs[4]) { - tokens.push(sets.notWords()); + var eos = this.eos(); + var tok = this.prev(); + if (tok.type !== 'eos') { + this.ast.nodes.push(eos); + } - } else if (rs[5]) { - tokens.push(sets.notInts()); + return this.ast; + } +}; - } else if (rs[6]) { - tokens.push(sets.notWhitespace()); +/** + * Visit `node` with the given `fn` + */ - } else if (rs[7]) { - tokens.push({ - type: types.RANGE, - from: (rs[8] || rs[9]).charCodeAt(0), - to: rs[10].charCodeAt(0), - }); +function visit(node, fn) { + if (!node.visited) { + define(node, 'visited', true); + return node.nodes ? mapVisit(node.nodes, fn) : fn(node); + } + return node; +} - } else if (c = rs[12]) { - tokens.push({ - type: types.CHAR, - value: c.charCodeAt(0), - }); +/** + * Map visit over array of `nodes`. + */ - } else { - return [tokens, regexp.lastIndex]; - } +function mapVisit(nodes, fn) { + var len = nodes.length; + var idx = -1; + while (++idx < len) { + visit(nodes[idx], fn); } +} - exports.error(regexpStr, 'Unterminated character class'); -}; +function hasOpen(node) { + return node.nodes && node.nodes[0].type === (node.type + '.open'); +} + +function hasClose(node) { + return node.nodes && utils.last(node.nodes).type === (node.type + '.close'); +} +function hasDelims(node) { + return hasOpen(node) && hasClose(node); +} /** - * Shortcut to throw errors. - * - * @param {String} regexp - * @param {String} msg + * Expose `Parser` */ -exports.error = function(regexp, msg) { - throw new SyntaxError('Invalid regular expression: /' + regexp + '/: ' + msg); -}; - - -/***/ }), -/* 621 */ -/***/ (function(module, exports) { -module.exports = { - ROOT : 0, - GROUP : 1, - POSITION : 2, - SET : 3, - RANGE : 4, - REPETITION : 5, - REFERENCE : 6, - CHAR : 7, -}; +module.exports = Parser; /***/ }), -/* 622 */ +/* 636 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(621); +"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 + */ -/***/ }), -/* 623 */ -/***/ (function(module, exports, __webpack_require__) { - -var types = __webpack_require__(621); - -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]; }; /***/ }), -/* 624 */ +/* 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__(535); -var isDescriptor = __webpack_require__(547); -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); }; /***/ }), -/* 625 */ +/* 638 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(626); -var assignSymbols = __webpack_require__(536); +var isExtendable = __webpack_require__(639); +var assignSymbols = __webpack_require__(544); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -72581,7 +75129,7 @@ function isEnum(obj, key) { /***/ }), -/* 626 */ +/* 639 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -72594,7 +75142,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(534); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -72602,93 +75150,14 @@ module.exports = function isExtendable(val) { /***/ }), -/* 627 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -var extend = __webpack_require__(625); -var safe = __webpack_require__(618); - -/** - * 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; - - -/***/ }), -/* 628 */ +/* 640 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(629); -var extglob = __webpack_require__(644); +var nanomatch = __webpack_require__(641); +var extglob = __webpack_require__(656); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -72765,7 +75234,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 629 */ +/* 641 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -72775,18 +75244,18 @@ function escapeExtglobs(compiler) { * Module dependencies */ -var util = __webpack_require__(111); -var toRegex = __webpack_require__(516); -var extend = __webpack_require__(630); +var util = __webpack_require__(112); +var toRegex = __webpack_require__(526); +var extend = __webpack_require__(642); /** * Local dependencies */ -var compilers = __webpack_require__(632); -var parsers = __webpack_require__(633); -var cache = __webpack_require__(636); -var utils = __webpack_require__(638); +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; /** @@ -73610,14 +76079,14 @@ module.exports = nanomatch; /***/ }), -/* 630 */ +/* 642 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(631); -var assignSymbols = __webpack_require__(536); +var isExtendable = __webpack_require__(643); +var assignSymbols = __webpack_require__(544); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -73677,7 +76146,7 @@ function isEnum(obj, key) { /***/ }), -/* 631 */ +/* 643 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -73690,7 +76159,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(534); +var isPlainObject = __webpack_require__(543); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -73698,7 +76167,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 632 */ +/* 644 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74044,15 +76513,15 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 633 */ +/* 645 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regexNot = __webpack_require__(527); -var toRegex = __webpack_require__(516); -var isOdd = __webpack_require__(634); +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 @@ -74438,7 +76907,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 634 */ +/* 646 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74451,7 +76920,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(635); +var isNumber = __webpack_require__(647); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -74465,7 +76934,7 @@ module.exports = function isOdd(i) { /***/ }), -/* 635 */ +/* 647 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74493,14 +76962,14 @@ module.exports = function isNumber(num) { /***/ }), -/* 636 */ +/* 648 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(637))(); +module.exports = new (__webpack_require__(649))(); /***/ }), -/* 637 */ +/* 649 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74513,7 +76982,7 @@ module.exports = new (__webpack_require__(637))(); -var MapCache = __webpack_require__(615); +var MapCache = __webpack_require__(636); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -74635,7 +77104,7 @@ exports = module.exports = FragmentCache; /***/ }), -/* 638 */ +/* 650 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74648,14 +77117,14 @@ var path = __webpack_require__(4); * Module dependencies */ -var isWindows = __webpack_require__(639)(); -var Snapdragon = __webpack_require__(555); -utils.define = __webpack_require__(640); -utils.diff = __webpack_require__(641); -utils.extend = __webpack_require__(630); -utils.pick = __webpack_require__(642); -utils.typeOf = __webpack_require__(643); -utils.unique = __webpack_require__(528); +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 @@ -75021,7 +77490,7 @@ utils.unixify = function(options) { /***/ }), -/* 639 */ +/* 651 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -75049,7 +77518,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 640 */ +/* 652 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75062,8 +77531,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ -var isobject = __webpack_require__(535); -var isDescriptor = __webpack_require__(547); +var isobject = __webpack_require__(534); +var isDescriptor = __webpack_require__(535); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -75094,7 +77563,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 641 */ +/* 653 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75148,7 +77617,7 @@ function diffArray(one, two) { /***/ }), -/* 642 */ +/* 654 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75161,7 +77630,7 @@ function diffArray(one, two) { -var isObject = __webpack_require__(535); +var isObject = __webpack_require__(534); module.exports = function pick(obj, keys) { if (!isObject(obj) && typeof obj !== 'function') { @@ -75190,7 +77659,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 643 */ +/* 655 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -75325,7 +77794,7 @@ function isBuffer(val) { /***/ }), -/* 644 */ +/* 656 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75335,18 +77804,18 @@ function isBuffer(val) { * Module dependencies */ -var extend = __webpack_require__(525); -var unique = __webpack_require__(528); -var toRegex = __webpack_require__(516); +var extend = __webpack_require__(549); +var unique = __webpack_require__(548); +var toRegex = __webpack_require__(526); /** * Local dependencies */ -var compilers = __webpack_require__(645); -var parsers = __webpack_require__(656); -var Extglob = __webpack_require__(659); -var utils = __webpack_require__(658); +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; /** @@ -75663,13 +78132,13 @@ module.exports = extglob; /***/ }), -/* 645 */ +/* 657 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(646); +var brackets = __webpack_require__(658); /** * Extglob compilers @@ -75839,7 +78308,7 @@ module.exports = function(extglob) { /***/ }), -/* 646 */ +/* 658 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75849,17 +78318,17 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(647); -var parsers = __webpack_require__(649); +var compilers = __webpack_require__(659); +var parsers = __webpack_require__(661); /** * Module dependencies */ -var debug = __webpack_require__(651)('expand-brackets'); -var extend = __webpack_require__(525); -var Snapdragon = __webpack_require__(555); -var toRegex = __webpack_require__(516); +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 @@ -76057,13 +78526,13 @@ module.exports = brackets; /***/ }), -/* 647 */ +/* 659 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(648); +var posix = __webpack_require__(660); module.exports = function(brackets) { brackets.compiler @@ -76151,7 +78620,7 @@ module.exports = function(brackets) { /***/ }), -/* 648 */ +/* 660 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76180,14 +78649,14 @@ module.exports = { /***/ }), -/* 649 */ +/* 661 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(650); -var define = __webpack_require__(517); +var utils = __webpack_require__(662); +var define = __webpack_require__(596); /** * Text regex @@ -76406,14 +78875,14 @@ module.exports.TEXT_REGEX = TEXT_REGEX; /***/ }), -/* 650 */ +/* 662 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var toRegex = __webpack_require__(516); -var regexNot = __webpack_require__(527); +var toRegex = __webpack_require__(526); +var regexNot = __webpack_require__(545); var cached; /** @@ -76447,7 +78916,7 @@ exports.createRegex = function(pattern, include) { /***/ }), -/* 651 */ +/* 663 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -76456,14 +78925,14 @@ exports.createRegex = function(pattern, include) { */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(652); + module.exports = __webpack_require__(664); } else { - module.exports = __webpack_require__(655); + module.exports = __webpack_require__(667); } /***/ }), -/* 652 */ +/* 664 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -76472,7 +78941,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(653); +exports = module.exports = __webpack_require__(665); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -76654,7 +79123,7 @@ function localstorage() { /***/ }), -/* 653 */ +/* 665 */ /***/ (function(module, exports, __webpack_require__) { @@ -76670,7 +79139,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(654); +exports.humanize = __webpack_require__(666); /** * The currently active debug mode names, and names to skip. @@ -76862,7 +79331,7 @@ function coerce(val) { /***/ }), -/* 654 */ +/* 666 */ /***/ (function(module, exports) { /** @@ -77020,15 +79489,15 @@ function plural(ms, n, name) { /***/ }), -/* 655 */ +/* 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()`. @@ -77036,7 +79505,7 @@ var util = __webpack_require__(111); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(653); +exports = module.exports = __webpack_require__(665); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -77208,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__(593); + var net = __webpack_require__(614); stream = new net.Socket({ fd: fd, readable: false, @@ -77274,15 +79743,15 @@ exports.enable(load()); /***/ }), -/* 656 */ +/* 668 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(646); -var define = __webpack_require__(657); -var utils = __webpack_require__(658); +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 @@ -77437,7 +79906,7 @@ module.exports = parsers; /***/ }), -/* 657 */ +/* 669 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77450,7 +79919,7 @@ module.exports = parsers; -var isDescriptor = __webpack_require__(547); +var isDescriptor = __webpack_require__(535); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -77475,14 +79944,14 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 658 */ +/* 670 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regex = __webpack_require__(527); -var Cache = __webpack_require__(637); +var regex = __webpack_require__(545); +var Cache = __webpack_require__(649); /** * Utils @@ -77551,7 +80020,7 @@ utils.createRegex = function(str) { /***/ }), -/* 659 */ +/* 671 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77561,16 +80030,16 @@ utils.createRegex = function(str) { * Module dependencies */ -var Snapdragon = __webpack_require__(555); -var define = __webpack_require__(657); -var extend = __webpack_require__(525); +var Snapdragon = __webpack_require__(569); +var define = __webpack_require__(669); +var extend = __webpack_require__(549); /** * Local dependencies */ -var compilers = __webpack_require__(645); -var parsers = __webpack_require__(656); +var compilers = __webpack_require__(657); +var parsers = __webpack_require__(668); /** * Customize Snapdragon parser and renderer @@ -77636,16 +80105,16 @@ module.exports = Extglob; /***/ }), -/* 660 */ +/* 672 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(644); -var nanomatch = __webpack_require__(629); -var regexNot = __webpack_require__(527); -var toRegex = __webpack_require__(617); +var extglob = __webpack_require__(656); +var nanomatch = __webpack_require__(641); +var regexNot = __webpack_require__(545); +var toRegex = __webpack_require__(526); var not; /** @@ -77726,14 +80195,14 @@ function textRegex(pattern) { /***/ }), -/* 661 */ +/* 673 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(637))(); +module.exports = new (__webpack_require__(649))(); /***/ }), -/* 662 */ +/* 674 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77746,13 +80215,13 @@ var path = __webpack_require__(4); * Module dependencies */ -var Snapdragon = __webpack_require__(555); -utils.define = __webpack_require__(624); -utils.diff = __webpack_require__(641); -utils.extend = __webpack_require__(625); -utils.pick = __webpack_require__(642); -utils.typeOf = __webpack_require__(663); -utils.unique = __webpack_require__(528); +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 `\\`. @@ -78049,7 +80518,52 @@ utils.unixify = function(options) { /***/ }), -/* 663 */ +/* 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; @@ -78184,7 +80698,7 @@ function isBuffer(val) { /***/ }), -/* 664 */ +/* 677 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78203,9 +80717,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(665); -var reader_1 = __webpack_require__(678); -var fs_stream_1 = __webpack_require__(682); +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() { @@ -78266,15 +80780,15 @@ exports.default = ReaderAsync; /***/ }), -/* 665 */ +/* 678 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(666); -const readdirAsync = __webpack_require__(674); -const readdirStream = __webpack_require__(677); +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; @@ -78358,7 +80872,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 666 */ +/* 679 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78366,11 +80880,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(667); +const DirectoryReader = __webpack_require__(680); let syncFacade = { - fs: __webpack_require__(672), - forEach: __webpack_require__(673), + fs: __webpack_require__(685), + forEach: __webpack_require__(686), sync: true }; @@ -78399,18 +80913,18 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 667 */ +/* 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__(668); -const stat = __webpack_require__(670); -const call = __webpack_require__(671); +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 @@ -78786,14 +81300,14 @@ module.exports = DirectoryReader; /***/ }), -/* 668 */ +/* 681 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const globToRegExp = __webpack_require__(669); +const globToRegExp = __webpack_require__(682); module.exports = normalizeOptions; @@ -78970,7 +81484,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 669 */ +/* 682 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -79107,13 +81621,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 670 */ +/* 683 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(671); +const call = __webpack_require__(684); module.exports = stat; @@ -79188,7 +81702,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 671 */ +/* 684 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79249,14 +81763,14 @@ function callOnce (fn) { /***/ }), -/* 672 */ +/* 685 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(133); -const call = __webpack_require__(671); +const fs = __webpack_require__(134); +const call = __webpack_require__(684); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -79320,7 +81834,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 673 */ +/* 686 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79349,7 +81863,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 674 */ +/* 687 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79357,12 +81871,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(675); -const DirectoryReader = __webpack_require__(667); +const maybe = __webpack_require__(688); +const DirectoryReader = __webpack_require__(680); let asyncFacade = { - fs: __webpack_require__(133), - forEach: __webpack_require__(676), + fs: __webpack_require__(134), + forEach: __webpack_require__(689), async: true }; @@ -79404,7 +81918,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 675 */ +/* 688 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79431,7 +81945,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 676 */ +/* 689 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79467,7 +81981,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 677 */ +/* 690 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79475,11 +81989,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(667); +const DirectoryReader = __webpack_require__(680); let streamFacade = { - fs: __webpack_require__(133), - forEach: __webpack_require__(676), + fs: __webpack_require__(134), + forEach: __webpack_require__(689), async: true }; @@ -79499,16 +82013,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 678 */ +/* 691 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var deep_1 = __webpack_require__(679); -var entry_1 = __webpack_require__(681); -var pathUtil = __webpack_require__(680); +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; @@ -79574,14 +82088,14 @@ exports.default = Reader; /***/ }), -/* 679 */ +/* 692 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(680); -var patternUtils = __webpack_require__(509); +var pathUtils = __webpack_require__(693); +var patternUtils = __webpack_require__(520); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { this.options = options; @@ -79664,7 +82178,7 @@ exports.default = DeepFilter; /***/ }), -/* 680 */ +/* 693 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79695,14 +82209,14 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 681 */ +/* 694 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(680); -var patternUtils = __webpack_require__(509); +var pathUtils = __webpack_require__(693); +var patternUtils = __webpack_require__(520); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { this.options = options; @@ -79787,7 +82301,7 @@ exports.default = EntryFilter; /***/ }), -/* 682 */ +/* 695 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79806,9 +82320,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var stream = __webpack_require__(137); -var fsStat = __webpack_require__(683); -var fs_1 = __webpack_require__(687); +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() { @@ -79858,14 +82372,14 @@ exports.default = FileSystemStream; /***/ }), -/* 683 */ +/* 696 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(684); -const statProvider = __webpack_require__(686); +const optionsManager = __webpack_require__(697); +const statProvider = __webpack_require__(699); /** * Asynchronous API. */ @@ -79896,13 +82410,13 @@ exports.statSync = statSync; /***/ }), -/* 684 */ +/* 697 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(685); +const fsAdapter = __webpack_require__(698); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -79915,13 +82429,13 @@ exports.prepare = prepare; /***/ }), -/* 685 */ +/* 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, @@ -79938,7 +82452,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 686 */ +/* 699 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79990,7 +82504,7 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 687 */ +/* 700 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80021,7 +82535,7 @@ exports.default = FileSystem; /***/ }), -/* 688 */ +/* 701 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80040,10 +82554,10 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var stream = __webpack_require__(137); -var readdir = __webpack_require__(665); -var reader_1 = __webpack_require__(678); -var fs_stream_1 = __webpack_require__(682); +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) { @@ -80111,7 +82625,7 @@ exports.default = ReaderStream; /***/ }), -/* 689 */ +/* 702 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80130,9 +82644,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(665); -var reader_1 = __webpack_require__(678); -var fs_sync_1 = __webpack_require__(690); +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() { @@ -80192,7 +82706,7 @@ exports.default = ReaderSync; /***/ }), -/* 690 */ +/* 703 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80211,8 +82725,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(683); -var fs_1 = __webpack_require__(687); +var fsStat = __webpack_require__(696); +var fs_1 = __webpack_require__(700); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -80258,7 +82772,7 @@ exports.default = FileSystemSync; /***/ }), -/* 691 */ +/* 704 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80274,13 +82788,13 @@ exports.flatten = flatten; /***/ }), -/* 692 */ +/* 705 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var merge2 = __webpack_require__(288); +var merge2 = __webpack_require__(284); /** * Merge multiple streams and propagate their errors into one stream in parallel. */ @@ -80295,13 +82809,13 @@ exports.merge = merge; /***/ }), -/* 693 */ +/* 706 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(694); +const pathType = __webpack_require__(707); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -80367,13 +82881,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 694 */ +/* 707 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fs = __webpack_require__(133); -const pify = __webpack_require__(695); +const fs = __webpack_require__(134); +const pify = __webpack_require__(708); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -80416,7 +82930,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 695 */ +/* 708 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80507,17 +83021,17 @@ module.exports = (obj, opts) => { /***/ }), -/* 696 */ +/* 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__(505); -const gitIgnore = __webpack_require__(697); -const pify = __webpack_require__(698); -const slash = __webpack_require__(699); +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/**', @@ -80615,7 +83129,7 @@ module.exports.sync = options => { /***/ }), -/* 697 */ +/* 710 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -81084,7 +83598,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 698 */ +/* 711 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81159,7 +83673,7 @@ module.exports = (input, options) => { /***/ }), -/* 699 */ +/* 712 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81177,71 +83691,17 @@ module.exports = input => { /***/ }), -/* 700 */ -/***/ (function(module, exports, __webpack_require__) { - -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -var isExtglob = __webpack_require__(299); -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; -}; - - -/***/ }), -/* 701 */ +/* 713 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const {constants: fsConstants} = __webpack_require__(133); -const pEvent = __webpack_require__(702); -const CpFileError = __webpack_require__(705); -const fs = __webpack_require__(709); -const ProgressEmitter = __webpack_require__(712); +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; @@ -81355,12 +83815,12 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 702 */ +/* 714 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pTimeout = __webpack_require__(703); +const pTimeout = __webpack_require__(715); const symbolAsyncIterator = Symbol.asyncIterator || '@@asyncIterator'; @@ -81651,12 +84111,12 @@ module.exports.iterator = (emitter, event, options) => { /***/ }), -/* 703 */ +/* 715 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pFinally = __webpack_require__(704); +const pFinally = __webpack_require__(716); class TimeoutError extends Error { constructor(message) { @@ -81702,7 +84162,7 @@ module.exports.TimeoutError = TimeoutError; /***/ }), -/* 704 */ +/* 716 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81724,12 +84184,12 @@ module.exports = (promise, onFinally) => { /***/ }), -/* 705 */ +/* 717 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(706); +const NestedError = __webpack_require__(718); class CpFileError extends NestedError { constructor(message, nested) { @@ -81743,15 +84203,17 @@ module.exports = CpFileError; /***/ }), -/* 706 */ +/* 718 */ /***/ (function(module, exports, __webpack_require__) { -var inherits = __webpack_require__(707); +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, @@ -81797,58 +84259,16 @@ module.exports = NestedError; /***/ }), -/* 707 */ -/***/ (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__(708); -} - - -/***/ }), -/* 708 */ -/***/ (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 - } -} - - -/***/ }), -/* 709 */ +/* 719 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const {promisify} = __webpack_require__(111); -const fs = __webpack_require__(132); -const makeDir = __webpack_require__(710); -const pEvent = __webpack_require__(702); -const CpFileError = __webpack_require__(705); +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); @@ -81945,15 +84365,15 @@ exports.copyFileSync = (source, destination, flags) => { /***/ }), -/* 710 */ +/* 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__(711); +const {promisify} = __webpack_require__(112); +const semver = __webpack_require__(721); const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); @@ -82108,7 +84528,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 711 */ +/* 721 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -83710,12 +86130,12 @@ function coerce (version, options) { /***/ }), -/* 712 */ +/* 722 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const EventEmitter = __webpack_require__(155); +const EventEmitter = __webpack_require__(156); const written = new WeakMap(); @@ -83751,7 +86171,7 @@ module.exports = ProgressEmitter; /***/ }), -/* 713 */ +/* 723 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83797,12 +86217,12 @@ exports.default = module.exports; /***/ }), -/* 714 */ +/* 724 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(715); +const NestedError = __webpack_require__(718); class CpyError extends NestedError { constructor(message, nested) { @@ -83815,61 +86235,5 @@ class CpyError extends NestedError { module.exports = CpyError; -/***/ }), -/* 715 */ -/***/ (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 c2f9236d9e798..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", @@ -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", @@ -50,13 +50,13 @@ "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 0c80c949c1d11..557f38ec740fc 100644 --- a/packages/kbn-spec-to-console/package.json +++ b/packages/kbn-spec-to-console/package.json @@ -17,7 +17,7 @@ }, "homepage": "https://github.com/jbudz/spec-to-console#readme", "devDependencies": { - "jest": "^25.5.4", + "jest": "^26.4.2", "prettier": "^2.1.1" }, "dependencies": { 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/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/package.json b/packages/kbn-storybook/package.json index 05fdb8489a1c3..58359159e950d 100644 --- a/packages/kbn-storybook/package.json +++ b/packages/kbn-storybook/package.json @@ -13,8 +13,8 @@ "@storybook/core": "^6.0.16", "@storybook/react": "^6.0.16", "@storybook/theming": "^6.0.16", - "@types/loader-utils": "^2.0.1", - "@types/webpack": "^4.41.5", + "@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", diff --git a/packages/kbn-storybook/webpack.config.ts b/packages/kbn-storybook/webpack.config.ts index 98fca597ffd78..84f8cfaefd669 100644 --- a/packages/kbn-storybook/webpack.config.ts +++ b/packages/kbn-storybook/webpack.config.ts @@ -100,9 +100,5 @@ export default function ({ config: storybookConfig }: { config: Configuration }) if (htmlWebpackPlugin) { htmlWebpackPlugin.options.template = require.resolve('../lib/templates/index.ejs'); } - - // @ts-expect-error There's a long error here about the types of the - // incompatibility of Configuration, but it looks like it just may be Webpack - // type definition related. return webpackMerge(storybookConfig, config); } diff --git a/packages/kbn-telemetry-tools/src/tools/serializer.test.ts b/packages/kbn-telemetry-tools/src/tools/serializer.test.ts index 652b26c8edb23..85fb84c714e20 100644 --- a/packages/kbn-telemetry-tools/src/tools/serializer.test.ts +++ b/packages/kbn-telemetry-tools/src/tools/serializer.test.ts @@ -138,4 +138,22 @@ describe('getDescriptor', () => { }, }); }); + + 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 cd845a680ad06..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, @@ -95,7 +95,16 @@ export function getConstraints(node: ts.Node, program: ts.Program): any { return node.literal.text; } - throw Error(`Unsupported constraint`); + 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 { @@ -157,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/utils.ts b/packages/kbn-telemetry-tools/src/tools/utils.ts index 947a4f66908f6..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; diff --git a/packages/kbn-test/package.json b/packages/kbn-test/package.json index c616c836d5ff4..4e86ec4bd72e0 100644 --- a/packages/kbn-test/package.json +++ b/packages/kbn-test/package.json @@ -32,7 +32,7 @@ "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", "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 be18b7cfc0d01..639d4e17d0e71 100644 --- a/packages/kbn-ui-framework/package.json +++ b/packages/kbn-ui-framework/package.json @@ -30,7 +30,7 @@ "enzyme-adapter-react-16": "^1.9.1" }, "devDependencies": { - "@babel/core": "^7.11.1", + "@babel/core": "^7.11.6", "@elastic/eui": "29.0.0", "@kbn/babel-preset": "1.0.0", "@kbn/optimizer": "1.0.0", @@ -38,7 +38,7 @@ "brace": "0.11.1", "chalk": "^4.1.0", "chokidar": "^3.4.2", - "core-js": "^3.6.4", + "core-js": "^3.6.5", "css-loader": "^3.4.2", "expose-loader": "^0.7.5", "file-loader": "^4.2.0", @@ -58,10 +58,10 @@ "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": "^4.0.5", "redux-thunk": "^2.3.0", "regenerator-runtime": "^0.13.3", "sass-loader": "^8.0.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-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/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 2d56496f2fdd2..53b01d8cb4414 100644 --- a/scripts/es.js +++ b/scripts/es.js @@ -17,7 +17,7 @@ * under the License. */ -require('../src/setup_node_env/prebuilt_dev_only_entry'); +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/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/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/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/setup_node_env/babel_register/polyfill.js b/src/cli/dist.js similarity index 63% rename from src/setup_node_env/babel_register/polyfill.js rename to src/cli/dist.js index b6928f6cb8caf..2e26eaf52e836 100644 --- a/src/setup_node_env/babel_register/polyfill.js +++ b/src/cli/dist.js @@ -17,13 +17,7 @@ * under the License. */ -// `@babel/preset-env` looks for and rewrites the following import -// statement into a list of import statements based on the polyfills -// necessary for our target environment (the current version of node) -// but since it does that during compilation, `import 'core-js/stable'` -// must be in a file that is loaded with `require()` AFTER `@babel/register` -// is configured. -// -// This is why we have this single statement in it's own file and require -// it from ./index.js +require('../apm')(); +require('../setup_node_env/no_transpilation'); require('core-js/stable'); +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/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/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.test.ts b/src/core/public/application/utils/parse_app_url.test.ts similarity index 58% rename from src/core/public/application/utils.test.ts rename to src/core/public/application/utils/parse_app_url.test.ts index ee1d82a7a872e..bf7e0a88a0742 100644 --- a/src/core/public/application/utils.test.ts +++ b/src/core/public/application/utils/parse_app_url.test.ts @@ -17,78 +17,16 @@ * 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`); - }); -}); +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 getOrigin = () => 'https://kibana.local:8080'; + const currentUrl = + 'https://kibana.local:8080/base-path/app/current/current-path?current-query=true'; const createApp = (props: Partial): App => { const app: App = { @@ -114,101 +52,178 @@ describe('parseAppUrl', () => { }); }); - describe('with relative paths', () => { + describe('with absolute paths', () => { it('parses the app id', () => { - expect(parseAppUrl('/base-path/app/foo', basePath, apps, getOrigin)).toEqual({ + expect(parseAppUrl('/base-path/app/foo', basePath, apps, currentUrl)).toEqual({ app: 'foo', path: undefined, }); - expect(parseAppUrl('/base-path/custom-bar', basePath, apps, getOrigin)).toEqual({ + 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, getOrigin)).toEqual({ + 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, getOrigin)).toEqual( - { - app: 'bar', - path: '/another/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, getOrigin)).toEqual({ + 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, getOrigin)).toEqual({ + 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, getOrigin)).toEqual( - { - app: 'foo', - path: '/path?hello=dolly', - } - ); - expect(parseAppUrl('/base-path/app/foo/path#hash/bang', basePath, apps, getOrigin)).toEqual({ + 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, getOrigin) + 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, getOrigin)).toEqual({ + 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, getOrigin)).toEqual({ + 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, getOrigin) + 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, getOrigin) + 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, getOrigin) + 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, getOrigin)).toEqual( + expect(parseAppUrl('/base-path/app/non-registered', basePath, apps, currentUrl)).toEqual( undefined ); - expect(parseAppUrl('/base-path/unknown-path', basePath, apps, getOrigin)).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, getOrigin) + 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, getOrigin) + parseAppUrl('https://kibana.local:8080/base-path/custom-bar', basePath, apps, currentUrl) ).toEqual({ app: 'bar', path: undefined, @@ -220,7 +235,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/app/foo/some/path', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'foo', @@ -231,7 +246,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/custom-bar/another/path/', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'bar', @@ -244,7 +259,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/app/foo#hash/bang', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'foo', @@ -255,7 +270,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/app/foo?hello=dolly', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'foo', @@ -266,7 +281,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/app/foo/path?hello=dolly', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'foo', @@ -277,7 +292,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/app/foo/path#hash/bang', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'foo', @@ -288,7 +303,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/app/foo/path#hash/bang?hello=dolly', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'foo', @@ -301,7 +316,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/custom-bar#hash/bang', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'bar', @@ -312,7 +327,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/custom-bar?hello=dolly', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'bar', @@ -323,7 +338,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/custom-bar/path?hello=dolly', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'bar', @@ -334,7 +349,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/custom-bar/path#hash/bang', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'bar', @@ -345,7 +360,7 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/custom-bar/path#hash/bang?hello=dolly', basePath, apps, - getOrigin + currentUrl ) ).toEqual({ app: 'bar', @@ -358,11 +373,11 @@ describe('parseAppUrl', () => { 'https://kibana.local:8080/base-path/app/non-registered', basePath, apps, - getOrigin + currentUrl ) ).toEqual(undefined); expect( - parseAppUrl('https://kibana.local:8080/base-path/unknown-path', basePath, apps, getOrigin) + parseAppUrl('https://kibana.local:8080/base-path/unknown-path', basePath, apps, currentUrl) ).toEqual(undefined); }); it('returns undefined when origin does not match', () => { @@ -371,7 +386,7 @@ describe('parseAppUrl', () => { 'https://other-kibana.external:8080/base-path/app/foo', basePath, apps, - getOrigin + currentUrl ) ).toEqual(undefined); expect( @@ -379,62 +394,14 @@ describe('parseAppUrl', () => { 'https://other-kibana.external:8080/base-path/custom-bar', basePath, apps, - getOrigin + currentUrl ) ).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('returns undefined when the path does not contain the base path', () => { + expect(parseAppUrl('https://kibana.local:8080/app/foo', basePath, apps, currentUrl)).toEqual( + undefined + ); }); }); - - 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/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/header/__snapshots__/header.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/header.test.tsx.snap index 2db3eede16e25..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, @@ -2109,17 +2069,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, @@ -2190,7 +2140,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -2200,7 +2150,7 @@ exports[`Header renders 1`] = ` "thrownError": null, }, ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -2229,7 +2179,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": CombineLatestSubscriber { "_parentOrParents": Subscriber { "_parentOrParents": null, @@ -2295,17 +2245,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, @@ -2376,7 +2316,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -2386,7 +2326,7 @@ exports[`Header renders 1`] = ` "thrownError": null, }, ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -2477,17 +2417,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, @@ -2558,7 +2488,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -2569,7 +2499,7 @@ exports[`Header renders 1`] = ` }, [Circular], ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -2598,7 +2528,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": CombineLatestSubscriber { "_parentOrParents": Subscriber { "_parentOrParents": null, @@ -2663,17 +2593,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, @@ -2744,7 +2664,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -2755,7 +2675,7 @@ exports[`Header renders 1`] = ` }, [Circular], ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -3295,17 +3215,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, @@ -3376,7 +3286,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -3386,7 +3296,7 @@ exports[`Header renders 1`] = ` "thrownError": null, }, ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -3415,7 +3325,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": CombineLatestSubscriber { "_parentOrParents": Subscriber { "_parentOrParents": null, @@ -3481,17 +3391,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, @@ -3562,7 +3462,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -3572,7 +3472,7 @@ exports[`Header renders 1`] = ` "thrownError": null, }, ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -3663,17 +3563,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, @@ -3744,7 +3634,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -3755,7 +3645,7 @@ exports[`Header renders 1`] = ` }, [Circular], ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -3784,7 +3674,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": CombineLatestSubscriber { "_parentOrParents": Subscriber { "_parentOrParents": null, @@ -3849,17 +3739,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, @@ -3930,7 +3810,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -3941,7 +3821,7 @@ exports[`Header renders 1`] = ` }, [Circular], ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -4038,17 +3918,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, @@ -4119,7 +3989,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -4129,7 +3999,7 @@ exports[`Header renders 1`] = ` "thrownError": null, }, ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -4158,7 +4028,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": CombineLatestSubscriber { "_parentOrParents": Subscriber { "_parentOrParents": null, @@ -4224,17 +4094,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, @@ -4305,7 +4165,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -4315,7 +4175,7 @@ exports[`Header renders 1`] = ` "thrownError": null, }, ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -4406,17 +4266,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, @@ -4487,7 +4337,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -4498,7 +4348,7 @@ exports[`Header renders 1`] = ` }, [Circular], ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, @@ -4527,7 +4377,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 1, - "outerValue": [Circular], + "outerValue": undefined, "parent": CombineLatestSubscriber { "_parentOrParents": Subscriber { "_parentOrParents": null, @@ -4592,17 +4442,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, @@ -4673,7 +4513,7 @@ exports[`Header renders 1`] = ` "index": 1, "isStopped": false, "outerIndex": 0, - "outerValue": [Circular], + "outerValue": undefined, "parent": [Circular], "syncErrorThrowable": false, "syncErrorThrown": false, @@ -4684,7 +4524,7 @@ exports[`Header renders 1`] = ` }, [Circular], ], - "resultSelector": null, + "resultSelector": undefined, "syncErrorThrowable": true, "syncErrorThrown": false, "syncErrorValue": null, 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/public.api.md b/src/core/public/public.api.md index 5970c9a8571c4..f52d5b6fbd6a5 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -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/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/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 450be3b0e9a6c..7742dad150cfa 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1820,6 +1820,7 @@ export interface SavedObjectsBulkCreateObject { // (undocumented) id?: string; migrationVersion?: SavedObjectsMigrationVersion; + namespaces?: string[]; originId?: string; // (undocumented) references?: SavedObjectReference[]; @@ -1977,6 +1978,7 @@ export interface SavedObjectsCoreFieldMapping { export interface SavedObjectsCreateOptions extends SavedObjectsBaseOptions { id?: string; migrationVersion?: SavedObjectsMigrationVersion; + namespaces?: string[]; originId?: string; overwrite?: boolean; // (undocumented) @@ -2002,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 2770f288b6af8..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 @@ -159,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/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/fixtures/telemetry_collectors/constants.ts b/src/fixtures/telemetry_collectors/constants.ts index 60df05bac2aeb..8896c294676c4 100644 --- a/src/fixtures/telemetry_collectors/constants.ts +++ b/src/fixtures/telemetry_collectors/constants.ts @@ -66,3 +66,7 @@ export interface MappedTypes { [key in 'prop3']: number; }; } + +export type RecordWithKnownProps = Record; + +export type IndexedAccessType = Pick; 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/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/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/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/ui/typeahead/suggestions_component.tsx b/src/plugins/data/public/ui/typeahead/suggestions_component.tsx index 054c6318b9772..50ed9e9542d36 100644 --- a/src/plugins/data/public/ui/typeahead/suggestions_component.tsx +++ b/src/plugins/data/public/ui/typeahead/suggestions_component.tsx @@ -154,7 +154,7 @@ export class SuggestionsComponent extends Component { const StyledSuggestionsListDiv = styled.div` ${(props: { queryBarRect: DOMRect; verticalListPosition: string }) => ` position: absolute; - z-index: 999; + z-index: 4001; left: ${props.queryBarRect.left}px; width: ${props.queryBarRect.width}px; ${props.verticalListPosition}`} 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/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 36a7fee14cce1..cdc0f9f0e0451 100644 --- a/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss +++ b/src/plugins/embeddable/public/lib/panel/_embeddable_panel.scss @@ -54,9 +54,14 @@ .embPanel__titleInner { overflow: hidden; display: flex; + align-items: center; padding-right: $euiSizeS; } + .embPanel__titleTooltipAnchor { + max-width: 100%; + } + .embPanel__titleText { @include euiTextTruncate; } diff --git a/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx b/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx index 7dde84e510535..ea6a6a78c2b67 100644 --- a/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx +++ b/src/plugins/embeddable/public/lib/panel/panel_header/panel_header.tsx @@ -99,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; @@ -135,9 +124,10 @@ export function PanelHeader({ embeddable, headerId, }: PanelHeaderProps) { - const viewDescription = getViewDescription(embeddable); - const showTitle = !hidePanelTitle && (!isViewMode || title || viewDescription !== ''); - const showPanelBar = badges.length > 0 || notifications.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, @@ -175,26 +165,36 @@ export function PanelHeader({ ); } + const renderTitle = () => { + const titleComponent = showTitle ? ( + + {title || placeholderTitle} + + ) : undefined; + return description ? ( + + + {titleComponent} + + + ) : ( + titleComponent + ); + }; + return (

- {showTitle ? ( - - - {getAriaLabel()} - {renderTooltip(viewDescription)} - - ) : ( - {getAriaLabel()} - )} + {getAriaLabel()} + {renderTitle()} {renderBadges(badges, embeddable)}

{renderNotifications(notifications, embeddable)} 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/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/public/public.api.md b/src/plugins/expressions/public/public.api.md index 162f0ef6824f5..5c0fd8ab1a572 100644 --- a/src/plugins/expressions/public/public.api.md +++ b/src/plugins/expressions/public/public.api.md @@ -429,7 +429,7 @@ export interface ExpressionImage { // // @public (undocumented) export interface ExpressionRenderDefinition { - displayName: string; + displayName?: string; help?: string; name: string; render: (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise; diff --git a/src/plugins/expressions/server/server.api.md b/src/plugins/expressions/server/server.api.md index 6ac251ea005b4..d8872ee416017 100644 --- a/src/plugins/expressions/server/server.api.md +++ b/src/plugins/expressions/server/server.api.md @@ -401,7 +401,7 @@ export interface ExpressionImage { // // @public (undocumented) export interface ExpressionRenderDefinition { - displayName: string; + displayName?: string; help?: string; name: string; render: (domNode: HTMLElement, config: Config, handlers: IInterpreterRenderHandlers) => void | Promise; 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 91407ffcaf226..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,6 +24,7 @@ export const createAppNavigationHandler = (targetUrl: string) => (event: MouseEv if (event.altKey || event.metaKey || event.ctrlKey) { return; } + const { application, addBasePath } = getServices(); event.preventDefault(); - getServices().application.navigateToUrl(targetUrl); + application.navigateToUrl(addBasePath(targetUrl)); }; diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx index aec010d2dd3f8..4d1033d12d2b8 100644 --- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_time_field/step_time_field.test.tsx @@ -30,7 +30,7 @@ jest.mock('./components/time_field', () => ({ TimeField: 'TimeField' })); jest.mock('./components/advanced_options', () => ({ AdvancedOptions: 'AdvancedOptions' })); jest.mock('./components/action_buttons', () => ({ ActionButtons: 'ActionButtons' })); jest.mock('./../../lib', () => ({ - extractTimeFields: require.requireActual('./../../lib').extractTimeFields, + extractTimeFields: jest.requireActual('./../../lib').extractTimeFields, ensureMinimumTime: async (fields: IFieldType) => Promise.resolve(fields), })); diff --git a/src/plugins/kibana_react/public/field_button/field_button.tsx b/src/plugins/kibana_react/public/field_button/field_button.tsx index 97d1b32746120..4c0298a65ba5d 100644 --- a/src/plugins/kibana_react/public/field_button/field_button.tsx +++ b/src/plugins/kibana_react/public/field_button/field_button.tsx @@ -19,7 +19,8 @@ import './field_button.scss'; import classNames from 'classnames'; -import React, { ReactNode, HTMLAttributes } from 'react'; +import React, { ReactNode, HTMLAttributes, ButtonHTMLAttributes } from 'react'; +import { CommonProps } from '@elastic/eui'; export interface FieldButtonProps extends HTMLAttributes { /** @@ -56,7 +57,14 @@ export interface FieldButtonProps extends HTMLAttributes { * The component will render a ` ) : ( -
- {fieldIcon && {fieldIcon}} - {fieldName && {fieldName}} - {fieldInfoIcon &&
{fieldInfoIcon}
} +
+ {innerContent}
)} 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 4cd30d32698ed..ec32d582ce15b 100644 --- a/src/plugins/region_map/public/region_map_type.js +++ b/src/plugins/region_map/public/region_map_type.js @@ -32,7 +32,7 @@ export function createRegionMapTypeDefinition(dependencies) { return { name: 'region_map', - getDeprecationMessage, + getInfoMessage: getDeprecationMessage, title: i18n.translate('regionMap.mapVis.regionMapTitle', { defaultMessage: 'Region Map' }), description: i18n.translate('regionMap.mapVis.regionMapDescription', { defaultMessage: diff --git a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx index 1bc3dc8066520..0adf55ed6bebb 100644 --- a/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx +++ b/src/plugins/saved_objects_management/public/management_section/objects_table/saved_objects_table.test.tsx @@ -544,11 +544,13 @@ describe('SavedObjectsTable', () => { 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_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 bed1bbeabb044..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 @@ -80,15 +80,32 @@ exports[`TelemetryManagementSectionComponent renders as expected 1`] = ` />

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

, "displayName": "Provide usage statistics", diff --git a/src/plugins/vis_type_timelion/public/components/chart.tsx b/src/plugins/telemetry_management_section/public/components/opt_in_security_example_flyout.test.tsx similarity index 63% rename from src/plugins/vis_type_timelion/public/components/chart.tsx rename to src/plugins/telemetry_management_section/public/components/opt_in_security_example_flyout.test.tsx index 15a376d4e9638..c80d0daf5a695 100644 --- a/src/plugins/vis_type_timelion/public/components/chart.tsx +++ b/src/plugins/telemetry_management_section/public/components/opt_in_security_example_flyout.test.tsx @@ -16,26 +16,12 @@ * 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'; -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 }; +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 0e2855f055540..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 @@ -212,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'); @@ -221,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 9ae0a3d12fbb5..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,6 +34,7 @@ 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 { OptInSecurityExampleFlyout } from './opt_in_security_example_flyout'; import { LazyField } from '../../../advanced_settings/public'; import { ToastsStart } from '../../../../core/public'; @@ -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 && } @@ -197,12 +201,25 @@ export class TelemetryManagementSection extends Component { />

- - - + + + + ), + 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 cc19a8bbcef91..411eaa96d8bfe 100644 --- a/src/plugins/tile_map/public/tile_map_type.js +++ b/src/plugins/tile_map/public/tile_map_type.js @@ -33,7 +33,7 @@ export function createTileMapTypeDefinition(dependencies) { return { name: 'tile_map', - getDeprecationMessage, + getInfoMessage: 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/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 {
} > - + , 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/_panel.scss b/src/plugins/vis_type_timelion/public/components/_timelion_vis.scss similarity index 88% rename from src/plugins/vis_type_timelion/public/components/_panel.scss rename to src/plugins/vis_type_timelion/public/components/_timelion_vis.scss index c4d591bc82cad..6729d400523cd 100644 --- a/src/plugins/vis_type_timelion/public/components/_panel.scss +++ b/src/plugins/vis_type_timelion/public/components/_timelion_vis.scss @@ -58,3 +58,11 @@ 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/_index.scss b/src/plugins/vis_type_timelion/public/components/index.scss similarity index 60% rename from src/plugins/vis_type_timelion/public/components/_index.scss rename to src/plugins/vis_type_timelion/public/components/index.scss index 707c9dafebe2b..a541c66e6e913 100644 --- a/src/plugins/vis_type_timelion/public/components/_index.scss +++ b/src/plugins/vis_type_timelion/public/components/index.scss @@ -1,2 +1,2 @@ -@import 'panel'; +@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/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/panel.tsx b/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx similarity index 90% rename from src/plugins/vis_type_timelion/public/components/panel.tsx rename to src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx index 9c30a6b75d6db..a7b623ac8680c 100644 --- a/src/plugins/vis_type_timelion/public/components/panel.tsx +++ b/src/plugins/vis_type_timelion/public/components/timelion_vis_component.tsx @@ -21,7 +21,9 @@ 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'; @@ -38,18 +40,19 @@ 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'; + +import './index.scss'; interface CrosshairPlot extends jquery.flot.plot { setCrosshair: (pos: Position) => void; clearCrosshair: () => void; } -interface PanelProps { - applyFilter: ExprVisAPIEvents['applyFilter']; +interface TimelionVisComponentProps { + fireEvent: IInterpreterRenderHandlers['event']; interval: string; seriesList: Sheet; - renderComplete(): void; + renderComplete: IInterpreterRenderHandlers['done']; } interface Position { @@ -75,11 +78,16 @@ 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) { +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(); + const [chartElem, setChartElem] = useState(null); const [originalColorMap, setOriginalColorMap] = useState(() => new Map()); @@ -191,7 +199,7 @@ function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps interval, kibana.services.timefilter, kibana.services.uiSettings, - chartElem && chartElem.clientWidth, + chartElem?.clientWidth, grid ); const updatedSeries = buildSeriesData(chartValue, options); @@ -216,12 +224,14 @@ function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps updateCaption(newPlot.getData()); } }, - [canvasElem, chartElem, renderComplete, kibana.services, interval, updateCaption] + [canvasElem, chartElem?.clientWidth, renderComplete, kibana.services, interval, updateCaption] ); + const dimensions = useResizeObserver(chartElem); + useEffect(() => { updatePlot(chart, seriesList.render && seriesList.render.grid); - }, [chart, updatePlot, seriesList.render]); + }, [chart, updatePlot, seriesList.render, dimensions]); useEffect(() => { const colorsSet: Array<[Series, string]> = []; @@ -349,21 +359,24 @@ function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps const plotSelectedHandler = useCallback( (event: JQuery.TriggeredEvent, ranges: Ranges) => { - applyFilter({ - timeFieldName: '*', - filters: [ - { - range: { - '*': { - gte: ranges.xaxis.from, - lte: ranges.xaxis.to, + fireEvent({ + name: 'applyFilter', + data: { + timeFieldName: '*', + filters: [ + { + range: { + '*': { + gte: ranges.xaxis.from, + lte: ranges.xaxis.to, + }, }, }, - }, - ], + ], + }, }); }, - [applyFilter] + [fireEvent] ); useEffect(() => { @@ -396,4 +409,6 @@ function Panel({ interval, seriesList, renderComplete, applyFilter }: PanelProps ); } -export { Panel }; +// 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_vega/public/__snapshots__/vega_visualization.test.js.snap b/src/plugins/vis_type_vega/public/__snapshots__/vega_visualization.test.js.snap index 0d38d9775a4cd..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 @@ -4,6 +4,6 @@ exports[`VegaVisualizations VegaVisualization - basics should show vega blank re 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/components/experimental_map_vis_info.tsx b/src/plugins/vis_type_vega/public/components/experimental_map_vis_info.tsx new file mode 100644 index 0000000000000..4f8bc50bb1b3b --- /dev/null +++ b/src/plugins/vis_type_vega/public/components/experimental_map_vis_info.tsx @@ -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. + */ + +import { parse } from 'hjson'; +import React from 'react'; +import { EuiCallOut, EuiLink } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { Vis } from '../../../visualizations/public'; + +function ExperimentalMapLayerInfo() { + const title = ( + + GitHub + + ), + }} + /> + ); + + return ( + + ); +} + +export const getInfoMessage = (vis: Vis) => { + if (vis.params.spec) { + try { + const spec = parse(vis.params.spec, { legacyRoot: false, keepWsc: true }); + + if (spec.config?.kibana?.type === 'map') { + return ; + } + } catch (e) { + // spec is invalid + } + } + + return null; +}; 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_type.ts b/src/plugins/vis_type_vega/public/vega_type.ts index 46fd2fbc5587e..a9651c1f5eb33 100644 --- a/src/plugins/vis_type_vega/public/vega_type.ts +++ b/src/plugins/vis_type_vega/public/vega_type.ts @@ -29,6 +29,8 @@ import { getDefaultSpec } from './default_spec'; import { createInspectorAdapters } from './vega_inspector'; import { VIS_EVENT_TO_TRIGGER } from '../../visualizations/public'; +import { getInfoMessage } from './components/experimental_map_vis_info'; + export const createVegaTypeDefinition = (dependencies: VegaVisualizationDependencies) => { const requestHandler = createVegaRequestHandler(dependencies); const visualization = createVegaVisualization(dependencies); @@ -36,6 +38,7 @@ export const createVegaTypeDefinition = (dependencies: VegaVisualizationDependen return { name: 'vega', title: 'Vega', + getInfoMessage, description: i18n.translate('visTypeVega.type.vegaDescription', { defaultMessage: 'Create custom visualizations using Vega and Vega-Lite', description: 'Vega and Vega-Lite are product names and should not be translated', 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_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/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 de1afc254e0d3..4763bc9de9d27 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<{}>; + getInfoMessage?: (vis: Vis) => ReactElement<{}> | null; } interface ExpressionBaseVisTypeOptions extends CommonBaseVisTypeOptions { @@ -84,7 +84,7 @@ export class BaseVisType { useCustomNoDataScreen: boolean; inspectorAdapters?: Adapters | (() => Adapters); toExpressionAst?: VisToExpressionAst; - getDeprecationMessage?: (vis: Vis) => ReactElement<{}>; + getInfoMessage?: (vis: Vis) => ReactElement<{}> | null; constructor(opts: BaseVisTypeOptions) { if (!opts.icon && !opts.image) { @@ -122,7 +122,7 @@ export class BaseVisType { this.useCustomNoDataScreen = opts.useCustomNoDataScreen || false; this.inspectorAdapters = opts.inspectorAdapters; this.toExpressionAst = opts.toExpressionAst; - this.getDeprecationMessage = opts.getDeprecationMessage; + this.getInfoMessage = opts.getInfoMessage; } public get schemas() { diff --git a/src/plugins/visualize/public/application/components/visualize_editor_common.tsx b/src/plugins/visualize/public/application/components/visualize_editor_common.tsx index 4b7b4dae02d0a..37f564aaa3a18 100644 --- a/src/plugins/visualize/public/application/components/visualize_editor_common.tsx +++ b/src/plugins/visualize/public/application/components/visualize_editor_common.tsx @@ -79,7 +79,7 @@ export const VisualizeEditorCommon = ({ /> )} {visInstance?.vis?.type?.isExperimental && } - {visInstance?.vis?.type?.getDeprecationMessage?.(visInstance.vis)} + {visInstance?.vis?.type?.getInfoMessage?.(visInstance.vis)} {visInstance && (

diff --git a/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx b/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx index 12720f3f22e7c..cb68a647cb81d 100644 --- a/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx +++ b/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx @@ -175,54 +175,61 @@ export const getTopNavConfig = ( }; const topNavMenu: TopNavMenuData[] = [ - ...(originatingApp && ((savedVis && savedVis.id) || embeddableId) - ? [ - { - id: 'saveAndReturn', - label: i18n.translate('visualize.topNavMenu.saveAndReturnVisualizationButtonLabel', { - defaultMessage: 'Save and return', - }), - emphasize: true, - iconType: 'check', - description: i18n.translate( - 'visualize.topNavMenu.saveAndReturnVisualizationButtonAriaLabel', - { - defaultMessage: 'Finish editing visualization and return to the last app', - } - ), - testId: 'visualizesaveAndReturnButton', - disableButton: hasUnappliedChanges, - tooltip() { - if (hasUnappliedChanges) { - return i18n.translate( - 'visualize.topNavMenu.saveAndReturnVisualizationDisabledButtonTooltip', - { - defaultMessage: 'Apply or Discard your changes before finishing', - } - ); - } - }, - run: async () => { - const saveOptions = { - confirmOverwrite: false, - returnToOrigin: true, - }; - if ( - originatingApp === 'dashboards' && - dashboard.dashboardFeatureFlagConfig.allowByValueEmbeddables && - !savedVis - ) { - return createVisReference(); - } - return doSave(saveOptions); + { + id: 'inspector', + label: i18n.translate('visualize.topNavMenu.openInspectorButtonLabel', { + defaultMessage: 'inspect', + }), + description: i18n.translate('visualize.topNavMenu.openInspectorButtonAriaLabel', { + defaultMessage: 'Open Inspector for visualization', + }), + testId: 'openInspectorButton', + disableButton() { + return !embeddableHandler.hasInspector || !embeddableHandler.hasInspector(); + }, + run: openInspector, + tooltip() { + if (!embeddableHandler.hasInspector || !embeddableHandler.hasInspector()) { + return i18n.translate('visualize.topNavMenu.openInspectorDisabledButtonTooltip', { + defaultMessage: `This visualization doesn't support any inspectors.`, + }); + } + }, + }, + { + id: 'share', + label: i18n.translate('visualize.topNavMenu.shareVisualizationButtonLabel', { + defaultMessage: 'share', + }), + description: i18n.translate('visualize.topNavMenu.shareVisualizationButtonAriaLabel', { + defaultMessage: 'Share Visualization', + }), + testId: 'shareTopNavButton', + run: (anchorElement) => { + if (share && !embeddableId) { + // TODO: support sharing in by-value mode + share.toggleShareContextMenu({ + anchorElement, + allowEmbed: true, + allowShortUrl: visualizeCapabilities.createShortUrl, + shareableUrl: unhashUrl(window.location.href), + objectId: savedVis?.id, + objectType: 'visualization', + sharingData: { + title: savedVis?.title, }, - }, - ] - : []), + isDirty: hasUnappliedChanges || hasUnsavedChanges, + }); + } + }, + // disable the Share button if no action specified + disableButton: !share || !!embeddableId, + }, ...(visualizeCapabilities.save && !embeddableId ? [ { id: 'save', + iconType: savedVis?.id && originatingApp ? undefined : 'save', label: savedVis?.id && originatingApp ? i18n.translate('visualize.topNavMenu.saveVisualizationAsButtonLabel', { @@ -303,56 +310,50 @@ export const getTopNavConfig = ( }, ] : []), - { - id: 'share', - label: i18n.translate('visualize.topNavMenu.shareVisualizationButtonLabel', { - defaultMessage: 'share', - }), - description: i18n.translate('visualize.topNavMenu.shareVisualizationButtonAriaLabel', { - defaultMessage: 'Share Visualization', - }), - testId: 'shareTopNavButton', - run: (anchorElement) => { - if (share && !embeddableId) { - // TODO: support sharing in by-value mode - share.toggleShareContextMenu({ - anchorElement, - allowEmbed: true, - allowShortUrl: visualizeCapabilities.createShortUrl, - shareableUrl: unhashUrl(window.location.href), - objectId: savedVis?.id, - objectType: 'visualization', - sharingData: { - title: savedVis?.title, + ...(originatingApp && ((savedVis && savedVis.id) || embeddableId) + ? [ + { + id: 'saveAndReturn', + label: i18n.translate('visualize.topNavMenu.saveAndReturnVisualizationButtonLabel', { + defaultMessage: 'Save and return', + }), + emphasize: true, + iconType: 'checkInCircleFilled', + description: i18n.translate( + 'visualize.topNavMenu.saveAndReturnVisualizationButtonAriaLabel', + { + defaultMessage: 'Finish editing visualization and return to the last app', + } + ), + testId: 'visualizesaveAndReturnButton', + disableButton: hasUnappliedChanges, + tooltip() { + if (hasUnappliedChanges) { + return i18n.translate( + 'visualize.topNavMenu.saveAndReturnVisualizationDisabledButtonTooltip', + { + defaultMessage: 'Apply or Discard your changes before finishing', + } + ); + } }, - isDirty: hasUnappliedChanges || hasUnsavedChanges, - }); - } - }, - // disable the Share button if no action specified - disableButton: !share || !!embeddableId, - }, - { - id: 'inspector', - label: i18n.translate('visualize.topNavMenu.openInspectorButtonLabel', { - defaultMessage: 'inspect', - }), - description: i18n.translate('visualize.topNavMenu.openInspectorButtonAriaLabel', { - defaultMessage: 'Open Inspector for visualization', - }), - testId: 'openInspectorButton', - disableButton() { - return !embeddableHandler.hasInspector || !embeddableHandler.hasInspector(); - }, - run: openInspector, - tooltip() { - if (!embeddableHandler.hasInspector || !embeddableHandler.hasInspector()) { - return i18n.translate('visualize.topNavMenu.openInspectorDisabledButtonTooltip', { - defaultMessage: `This visualization doesn't support any inspectors.`, - }); - } - }, - }, + run: async () => { + const saveOptions = { + confirmOverwrite: false, + returnToOrigin: true, + }; + if ( + originatingApp === 'dashboards' && + dashboard.dashboardFeatureFlagConfig.allowByValueEmbeddables && + !savedVis + ) { + return createVisReference(); + } + return doSave(saveOptions); + }, + }, + ] + : []), ]; return topNavMenu; diff --git a/src/setup_node_env/babel_register/register.js b/src/setup_node_env/babel_register/register.js deleted file mode 100644 index 6d573d8922244..0000000000000 --- a/src/setup_node_env/babel_register/register.js +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -var resolve = require('path').resolve; - -// this must happen before `require('@babel/register')` and can't be changed -// once the module has been loaded -if (!process.env.BABEL_CACHE_PATH) { - process.env.BABEL_CACHE_PATH = resolve( - __dirname, - '../../../data/optimize/.babel_register_cache.json' - ); -} - -// paths that @babel/register should ignore -var ignore = [ - /[\/\\]bower_components[\/\\]/, - /[\/\\]kbn-pm[\/\\]dist[\/\\]/, - - // TODO: remove this and just transpile plugins at build time, but - // has tricky edge cases that will probably require better eslint - // restrictions to make sure that code destined for the server/browser - // follows respects the limitations of each environment. - // - // https://github.com/elastic/kibana/issues/14800#issuecomment-366130268 - - // 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[\/\\]/, -]; - -if (global.__BUILT_WITH_BABEL__) { - // when building the Kibana source we replace the statement - // `global.__BUILT_WITH_BABEL__` with the value `true` so that - // when @babel/register is required for the first time by users - // it will exclude kibana's `src` directory. - // - // We still need @babel/register for plugins though, we've been - // building their server code at require-time since version 4.2 - // TODO: the plugin install process could transpile plugin server code... - ignore.push(resolve(__dirname, '../../../src')); -} else { - ignore.push( - // 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)$)(.+$)/ - ); -} - -// modifies all future calls to require() to automatically -// compile the required source with babel -require('@babel/register')({ - ignore, - babelrc: false, - presets: [require.resolve('@kbn/babel-preset/node_preset')], - extensions: ['.js', '.ts', '.tsx'], -}); diff --git a/src/setup_node_env/index.js b/src/setup_node_env/index.js index d84249df7fd8f..55539c56a364e 100644 --- a/src/setup_node_env/index.js +++ b/src/setup_node_env/index.js @@ -17,5 +17,5 @@ * under the License. */ -require('./prebuilt_dev_only_entry'); -require('./babel_register'); +require('./no_transpilation'); +require('@kbn/optimizer').registerNodeAutoTranspilation(); diff --git a/src/setup_node_env/prebuilt_dev_only_entry.js b/src/setup_node_env/no_transpilation.js similarity index 100% rename from src/setup_node_env/prebuilt_dev_only_entry.js rename to src/setup_node_env/no_transpilation.js diff --git a/tasks/config/run.js b/tasks/config/run.js index 148be6ea8afaa..eddcb0bdd59d0 100644 --- a/tasks/config/run.js +++ b/tasks/config/run.js @@ -240,10 +240,6 @@ module.exports = function () { args: ['scripts/check_licenses', '--dev'], }), - verifyDependencyVersions: gruntTaskWithGithubChecks( - 'Verify dependency versions', - 'verifyDependencyVersions' - ), test_jest: gruntTaskWithGithubChecks('Jest tests', 'test:jest'), test_jest_integration: gruntTaskWithGithubChecks( 'Jest integration tests', diff --git a/tasks/jenkins.js b/tasks/jenkins.js index 90efadf41c435..4e3358ce81bbd 100644 --- a/tasks/jenkins.js +++ b/tasks/jenkins.js @@ -31,7 +31,6 @@ module.exports = function (grunt) { 'run:checkFileCasing', 'run:checkLockfileSymlinks', 'run:licenses', - 'run:verifyDependencyVersions', 'run:verifyNotice', 'run:mocha', 'run:test_jest', diff --git a/tasks/verify_dependency_versions.js b/tasks/verify_dependency_versions.js deleted file mode 100644 index 14ecbb9ba8603..0000000000000 --- a/tasks/verify_dependency_versions.js +++ /dev/null @@ -1,53 +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 { size } from 'lodash'; -import kibana from '../package.json'; -import xpack from '../x-pack/package.json'; - -function getMismatches(depType) { - return Object.keys(kibana[depType]) - .map((key) => { - const xpackValue = xpack[depType][key]; - const kibanaValue = kibana[depType][key]; - if (xpackValue && kibanaValue && xpackValue !== kibanaValue && !key.includes('@kbn/')) { - return { - key, - xpack: xpackValue, - kibana: kibanaValue, - }; - } - }) - .filter((key) => !!key); -} - -export default function verifyDependencyVersions(grunt) { - grunt.registerTask('verifyDependencyVersions', 'Checks dependency versions', () => { - const devDependenciesMismatches = getMismatches('devDependencies'); - if (size(devDependenciesMismatches) > 0) { - grunt.log.error( - 'The following devDependencies do not match:', - JSON.stringify(devDependenciesMismatches, null, 4) - ); - return false; - } else { - grunt.log.writeln('devDependencies match!'); - } - }); -} diff --git a/test/common/services/kibana_server/extend_es_archiver.js b/test/common/services/kibana_server/extend_es_archiver.js index 4efdfc4dddf77..f6e14061aed2a 100644 --- a/test/common/services/kibana_server/extend_es_archiver.js +++ b/test/common/services/kibana_server/extend_es_archiver.js @@ -33,9 +33,15 @@ export function extendEsArchiver({ esArchiver, kibanaServer, retry, defaults }) // esArchiver methods return a stats object, with information about the indexes created const stats = await originalMethod.apply(esArchiver, args); + const statsKeys = Object.keys(stats); + const kibanaKeys = statsKeys.filter( + // this also matches stats keys like '.kibana_1' and '.kibana_2,.kibana_1' + (key) => key.includes(KIBANA_INDEX) && (stats[key].created || stats[key].deleted) + ); + // if the kibana index was created by the esArchiver then update the uiSettings // with the defaults to make sure that they are always in place initially - if (stats[KIBANA_INDEX] && (stats[KIBANA_INDEX].created || stats[KIBANA_INDEX].deleted)) { + if (kibanaKeys.length > 0) { await retry.try(async () => { await kibanaServer.uiSettings.update(defaults); }); diff --git a/test/functional/apps/dashboard/dashboard_options.js b/test/functional/apps/dashboard/dashboard_options.js index d48e46e58f6d0..4e7c3f4cdc79b 100644 --- a/test/functional/apps/dashboard/dashboard_options.js +++ b/test/functional/apps/dashboard/dashboard_options.js @@ -44,7 +44,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.dashboard.checkHideTitle(); await retry.try(async () => { const titles = await PageObjects.dashboard.getPanelTitles(); - expect(titles[0]).to.eql(undefined); + expect(titles[0]).to.eql(''); }); }); diff --git a/test/functional/apps/visualize/_tsvb_chart.ts b/test/functional/apps/visualize/_tsvb_chart.ts index bfe0da7a5b24f..3e325d5e6b907 100644 --- a/test/functional/apps/visualize/_tsvb_chart.ts +++ b/test/functional/apps/visualize/_tsvb_chart.ts @@ -135,11 +135,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.visualBuilder.clickPanelOptions('metric'); const fromTime = 'Oct 22, 2018 @ 00:00:00.000'; const toTime = 'Oct 28, 2018 @ 23:59:59.999'; + await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); // Sometimes popovers take some time to appear in Firefox (#71979) await retry.tryForTime(20000, async () => { - await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime); await PageObjects.visualBuilder.setIndexPatternValue('kibana_sample_data_flights'); - await PageObjects.common.sleep(3000); + await PageObjects.visualBuilder.waitForIndexPatternTimeFieldOptionsLoaded(); await PageObjects.visualBuilder.selectIndexPatternTimeField('timestamp'); }); const newValue = await PageObjects.visualBuilder.getMetricValue(); diff --git a/test/functional/apps/visualize/_tsvb_time_series.ts b/test/functional/apps/visualize/_tsvb_time_series.ts index 0b2a52b367a20..d4a079a38c814 100644 --- a/test/functional/apps/visualize/_tsvb_time_series.ts +++ b/test/functional/apps/visualize/_tsvb_time_series.ts @@ -84,8 +84,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await visualBuilder.clickSeriesOption(); await visualBuilder.enterSeriesTemplate('$ {{value}}'); - const actualCount = await visualBuilder.getRhythmChartLegendValue(); - expect(actualCount).to.be(expectedLegendValue); + await retry.try(async () => { + const actualCount = await visualBuilder.getRhythmChartLegendValue(); + expect(actualCount).to.be(expectedLegendValue); + }); }); it('should show the correct count in the legend with percent formatter', async () => { diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index 6e49fd3b03494..37634d0248b04 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -453,6 +453,14 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro await PageObjects.header.waitUntilLoadingHasFinished(); } + public async waitForIndexPatternTimeFieldOptionsLoaded() { + await retry.waitFor('combobox options loaded', async () => { + const options = await comboBox.getOptions('metricsIndexPatternFieldsSelect'); + log.debug(`-- optionsCount=${options.length}`); + return options.length > 0; + }); + } + public async selectIndexPatternTimeField(timeField: string) { await retry.try(async () => { await comboBox.clearInputField('metricsIndexPatternFieldsSelect'); diff --git a/test/functional/services/combo_box.ts b/test/functional/services/combo_box.ts index ac7a40361d065..57e1857989950 100644 --- a/test/functional/services/combo_box.ts +++ b/test/functional/services/combo_box.ts @@ -58,6 +58,17 @@ export function ComboBoxProvider({ getService, getPageObjects }: FtrProviderCont return isMouseClick ? await element.clickMouseButton() : await element._webElement.click(); } + /** + * Finds combobox element options + * + * @param comboBoxSelector data-test-subj selector + */ + public async getOptions(comboBoxSelector: string) { + const comboBoxElement = await testSubjects.find(comboBoxSelector); + await this.openOptionsList(comboBoxElement); + return await find.allByCssSelector('.euiFilterSelectItem', WAIT_FOR_EXISTS_TIME); + } + /** * Sets value for specified combobox element * diff --git a/test/functional/services/common/failure_debugging.ts b/test/functional/services/common/failure_debugging.ts index aa67c455e0100..8b0e095b71ff8 100644 --- a/test/functional/services/common/failure_debugging.ts +++ b/test/functional/services/common/failure_debugging.ts @@ -38,7 +38,7 @@ export async function FailureDebuggingProvider({ getService }: FtrProviderContex const log = getService('log'); const browser = getService('browser'); - if (process.env.CI !== 'true') { + if (process.env.CI !== 'true' && !process.env.stack_functional_integration) { await del(config.get('failureDebugging.htmlDirectory')); } diff --git a/test/functional/services/common/screenshots.ts b/test/functional/services/common/screenshots.ts index daa55240f3eb7..5bce0d4cf6c87 100644 --- a/test/functional/services/common/screenshots.ts +++ b/test/functional/services/common/screenshots.ts @@ -40,7 +40,7 @@ export async function ScreenshotsProvider({ getService }: FtrProviderContext) { const FAILURE_DIRECTORY = resolve(config.get('screenshots.directory'), 'failure'); const BASELINE_DIRECTORY = resolve(config.get('screenshots.directory'), 'baseline'); - if (process.env.CI !== 'true') { + if (process.env.CI !== 'true' && !process.env.stack_functional_integration) { await del([SESSION_DIRECTORY, FAILURE_DIRECTORY]); } diff --git a/test/functional/services/common/snapshots.ts b/test/functional/services/common/snapshots.ts index 2e0b360e594e5..03eadff82e31f 100644 --- a/test/functional/services/common/snapshots.ts +++ b/test/functional/services/common/snapshots.ts @@ -35,7 +35,7 @@ export async function SnapshotsProvider({ getService }: FtrProviderContext) { const SESSION_DIRECTORY = resolve(config.get('snapshots.directory'), 'session'); const BASELINE_DIRECTORY = resolve(config.get('snapshots.directory'), 'baseline'); - if (process.env.CI !== 'true') { + if (process.env.CI !== 'true' && !process.env.stack_functional_integration) { await del([SESSION_DIRECTORY]); } diff --git a/test/scripts/checks/verify_dependency_versions.sh b/test/scripts/checks/verify_dependency_versions.sh deleted file mode 100755 index b73a71e7ff7fd..0000000000000 --- a/test/scripts/checks/verify_dependency_versions.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -source src/dev/ci_setup/setup_env.sh - -yarn run grunt run:verifyDependencyVersions diff --git a/vars/tasks.groovy b/vars/tasks.groovy index edd2c0aa47401..09ff1b0a7d95b 100644 --- a/vars/tasks.groovy +++ b/vars/tasks.groovy @@ -12,7 +12,6 @@ def check() { kibanaPipeline.scriptTask('Check File Casing', 'test/scripts/checks/file_casing.sh'), kibanaPipeline.scriptTask('Check Lockfile Symlinks', 'test/scripts/checks/lock_file_symlinks.sh'), kibanaPipeline.scriptTask('Check Licenses', 'test/scripts/checks/licenses.sh'), - kibanaPipeline.scriptTask('Verify Dependency Versions', 'test/scripts/checks/verify_dependency_versions.sh'), kibanaPipeline.scriptTask('Verify NOTICE', 'test/scripts/checks/verify_notice.sh'), kibanaPipeline.scriptTask('Test Projects', 'test/scripts/checks/test_projects.sh'), kibanaPipeline.scriptTask('Test Hardening', 'test/scripts/checks/test_hardening.sh'), diff --git a/x-pack/.telemetryrc.json b/x-pack/.telemetryrc.json index 9140dbdaf00ae..ae85efcda32d5 100644 --- a/x-pack/.telemetryrc.json +++ b/x-pack/.telemetryrc.json @@ -1,11 +1,5 @@ { "output": "plugins/telemetry_collection_xpack/schema/xpack_plugins.json", "root": "plugins/", - "exclude": [ - "plugins/actions/server/usage/actions_usage_collector.ts", - "plugins/alerts/server/usage/alerts_usage_collector.ts", - "plugins/apm/server/lib/apm_telemetry/index.ts", - "plugins/infra/server/usage/usage_collector.ts", - "plugins/maps/server/maps_telemetry/collectors/register.ts" - ] + "exclude": [] } diff --git a/x-pack/package.json b/x-pack/package.json index 97d673290abd1..ffe1a08855888 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -29,9 +29,10 @@ "**/@types/node": ">=10.17.17 <10.20.0" }, "devDependencies": { - "@cypress/webpack-preprocessor": "^4.1.0", - "@elastic/apm-rum-react": "^1.2.4", + "@cypress/webpack-preprocessor": "^5.4.1", + "@elastic/apm-rum-react": "^1.2.5", "@elastic/maki": "6.3.0", + "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@kbn/es": "1.0.0", "@kbn/expect": "1.0.0", @@ -88,7 +89,7 @@ "@types/hoist-non-react-statics": "^3.3.1", "@types/http-proxy": "^1.17.4", "@types/http-proxy-agent": "^2.0.2", - "@types/jest": "^25.2.3", + "@types/jest": "^26.0.14", "@types/jest-specific-snapshot": "^0.5.4", "@types/joi": "^13.4.2", "@types/js-search": "^1.4.0", @@ -127,7 +128,7 @@ "@types/styled-components": "^5.1.0", "@types/supertest": "^2.0.5", "@types/tar-fs": "^1.16.1", - "@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/tinycolor2": "^1.4.1", "@types/use-resize-observer": "^6.0.0", @@ -143,7 +144,7 @@ "apollo-link-error": "^1.1.7", "apollo-link-state": "^0.4.1", "autoprefixer": "^9.7.4", - "babel-jest": "^25.5.1", + "babel-jest": "^26.3.0", "babel-loader": "^8.0.6", "babel-plugin-require-context-hook": "npm:babel-plugin-require-context-hook-babel7@1.0.0", "base64-js": "^1.3.1", @@ -159,7 +160,7 @@ "copy-to-clipboard": "^3.0.8", "copy-webpack-plugin": "^6.0.2", "cronstrue": "^1.51.0", - "cypress": "5.0.0", + "cypress": "^5.0.0", "cypress-multi-reporters": "^1.2.3", "cypress-promise": "^1.1.0", "d3": "3.5.17", @@ -188,9 +189,9 @@ "hoist-non-react-statics": "^3.3.2", "i18n-iso-countries": "^4.3.1", "icalendar": "0.7.1", - "jest": "^25.5.4", - "jest-circus": "^25.5.4", - "jest-cli": "^25.5.4", + "jest": "^26.4.2", + "jest-circus": "^26.4.2", + "jest-cli": "^26.4.2", "jest-styled-components": "^7.0.2", "js-search": "^1.4.3", "jsdom": "13.1.0", @@ -257,7 +258,7 @@ "tinycolor2": "1.4.1", "topojson-client": "3.0.0", "tree-kill": "^1.2.2", - "ts-loader": "^6.0.4", + "ts-loader": "^7.0.5", "typescript": "4.0.2", "typescript-fsa": "^3.0.0", "typescript-fsa-reducers": "^1.2.1", @@ -270,8 +271,7 @@ "yargs": "^15.4.1" }, "dependencies": { - "@babel/core": "^7.11.1", - "@babel/register": "^7.10.5", + "@babel/core": "^7.11.6", "@babel/runtime": "^7.11.2", "@elastic/datemath": "5.0.3", "@elastic/ems-client": "7.10.0", @@ -280,7 +280,6 @@ "@elastic/node-crypto": "1.2.1", "@elastic/numeral": "^2.5.0", "@elastic/safer-lodash-set": "0.0.0", - "@kbn/babel-preset": "1.0.0", "@kbn/config-schema": "1.0.0", "@kbn/i18n": "1.0.0", "@kbn/interpreter": "1.0.0", @@ -309,7 +308,7 @@ "dedent": "^0.7.0", "del": "^5.1.0", "elasticsearch": "^16.7.0", - "extract-zip": "^1.7.0", + "extract-zip": "^2.0.1", "file-type": "^10.9.0", "font-awesome": "4.7.0", "fp-ts": "^2.3.1", @@ -321,7 +320,7 @@ "glob": "^7.1.2", "graphql": "^0.13.2", "graphql-fields": "^1.0.2", - "graphql-tag": "^2.9.2", + "graphql-tag": "^2.10.3", "graphql-tools": "^3.0.2", "h2o2": "^8.1.2", "handlebars": "4.7.6", @@ -334,7 +333,7 @@ "isbinaryfile": "4.0.2", "joi": "^13.5.2", "jquery": "^3.5.0", - "js-yaml": "3.13.1", + "js-yaml": "^3.14.0", "json-stable-stringify": "^1.0.1", "jsonwebtoken": "^8.5.1", "lodash": "^4.17.20", @@ -372,7 +371,7 @@ "redux-observable": "^1.2.0", "redux-thunk": "^2.3.0", "request": "^2.88.0", - "rison-node": "0.3.1", + "rison-node": "1.0.2", "rxjs": "^6.5.5", "semver": "^5.7.0", "set-value": "^3.0.2", diff --git a/x-pack/plugins/actions/server/builtin_action_types/email.test.ts b/x-pack/plugins/actions/server/builtin_action_types/email.test.ts index 7147483998d98..132510ea0ce84 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/email.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/email.test.ts @@ -55,6 +55,7 @@ describe('config validation', () => { const config: Record = { service: 'gmail', from: 'bob@example.com', + hasAuth: true, }; expect(validateConfig(actionType, config)).toEqual({ ...config, @@ -66,6 +67,7 @@ describe('config validation', () => { delete config.service; config.host = 'elastic.co'; config.port = 8080; + config.hasAuth = true; expect(validateConfig(actionType, config)).toEqual({ ...config, service: null, @@ -233,6 +235,7 @@ describe('execute()', () => { port: 42, secure: true, from: 'bob@example.com', + hasAuth: true, }; const secrets: ActionTypeSecretsType = { user: 'bob', @@ -269,6 +272,7 @@ describe('execute()', () => { "message": "a message to you", "subject": "the subject", }, + "hasAuth": true, "proxySettings": undefined, "routing": Object { "bcc": Array [ @@ -298,6 +302,7 @@ describe('execute()', () => { port: 42, secure: true, from: 'bob@example.com', + hasAuth: false, }; const secrets: ActionTypeSecretsType = { user: null, @@ -327,6 +332,7 @@ describe('execute()', () => { "message": "a message to you", "subject": "the subject", }, + "hasAuth": false, "proxySettings": undefined, "routing": Object { "bcc": Array [ @@ -356,6 +362,7 @@ describe('execute()', () => { port: 42, secure: true, from: 'bob@example.com', + hasAuth: false, }; const secrets: ActionTypeSecretsType = { user: null, diff --git a/x-pack/plugins/actions/server/builtin_action_types/email.ts b/x-pack/plugins/actions/server/builtin_action_types/email.ts index 6fd2d694b06f7..be2664887d943 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/email.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/email.ts @@ -36,6 +36,7 @@ const ConfigSchemaProps = { port: schema.nullable(portSchema()), secure: schema.nullable(schema.boolean()), from: schema.string(), + hasAuth: schema.boolean({ defaultValue: true }), }; const ConfigSchema = schema.object(ConfigSchemaProps); @@ -185,6 +186,7 @@ async function executor( message: params.message, }, proxySettings: execOptions.proxySettings, + hasAuth: config.hasAuth, }; let result; diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts index 605c05e2a9f25..fe4e135c76fc3 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts @@ -965,7 +965,7 @@ describe('Jira service', () => { axios, logger, method: 'get', - url: `https://siem-kibana.atlassian.net/rest/api/2/search?jql=project=CK and summary ~"Test title"`, + url: `https://siem-kibana.atlassian.net/rest/api/2/search?jql=project%3D%22CK%22%20and%20summary%20~%22Test%20title%22`, }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts index 7429c3d36d7b0..f52d3fa2efd37 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts @@ -396,7 +396,10 @@ export const createExternalService = ( }; const getIssues = async (title: string) => { - const query = `${searchUrl}?jql=project=${projectKey} and summary ~"${title}"`; + const query = `${searchUrl}?jql=${encodeURIComponent( + `project="${projectKey}" and summary ~"${title}"` + )}`; + try { const res = await request({ axios: axiosInstance, diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/send_email.test.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/send_email.test.ts index b6c4a4ea882e5..a1c4041628bd5 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/send_email.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/send_email.test.ts @@ -64,7 +64,7 @@ describe('send_email module', () => { }); test('handles unauthenticated email using not secure host/port', async () => { - const sendEmailOptions = getSendEmailOptions( + const sendEmailOptions = getSendEmailOptionsNoAuth( { transport: { host: 'example.com', @@ -76,12 +76,7 @@ describe('send_email module', () => { proxyRejectUnauthorizedCertificates: false, } ); - // @ts-expect-error - delete sendEmailOptions.transport.service; - // @ts-expect-error - delete sendEmailOptions.transport.user; - // @ts-expect-error - delete sendEmailOptions.transport.password; + const result = await sendEmail(mockLogger, sendEmailOptions); expect(result).toBe(sendMailMockResult); expect(createTransportMock.mock.calls[0]).toMatchInlineSnapshot(` @@ -248,5 +243,31 @@ function getSendEmailOptions( password: 'changeme', }, proxySettings, + hasAuth: true, + }; +} + +function getSendEmailOptionsNoAuth( + { content = {}, routing = {}, transport = {} } = {}, + proxySettings?: ProxySettings +) { + return { + content: { + ...content, + message: 'a message', + subject: 'a subject', + }, + routing: { + ...routing, + from: 'fred@example.com', + to: ['jim@example.com'], + cc: ['bob@example.com', 'robert@example.com'], + bcc: [], + }, + transport: { + ...transport, + }, + proxySettings, + hasAuth: false, }; } diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/send_email.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/send_email.ts index dead8fee63d4f..f3cdf82bfe8cd 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/send_email.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/send_email.ts @@ -20,6 +20,7 @@ export interface SendEmailOptions { content: Content; proxySettings?: ProxySettings; rejectUnauthorized?: boolean; + hasAuth: boolean; } // config validation ensures either service is set or host/port are set @@ -46,14 +47,14 @@ export interface Content { // send an email export async function sendEmail(logger: Logger, options: SendEmailOptions): Promise { - const { transport, routing, content, proxySettings, rejectUnauthorized } = options; + const { transport, routing, content, proxySettings, rejectUnauthorized, hasAuth } = options; const { service, host, port, secure, user, password } = transport; const { from, to, cc, bcc } = routing; const { subject, message } = content; const transportConfig: Record = {}; - if (user != null && password != null) { + if (hasAuth && user != null && password != null) { transportConfig.auth = { user, pass: password, diff --git a/x-pack/plugins/actions/server/saved_objects/migrations.test.ts b/x-pack/plugins/actions/server/saved_objects/migrations.test.ts index d577f0c8bbc6c..1fa5889e77cb0 100644 --- a/x-pack/plugins/actions/server/saved_objects/migrations.test.ts +++ b/x-pack/plugins/actions/server/saved_objects/migrations.test.ts @@ -21,6 +21,20 @@ describe('7.10.0', () => { ); }); + test('add hasAuth config property for .email actions', () => { + const migration710 = getMigrations(encryptedSavedObjectsSetup)['7.10.0']; + const action = getMockDataForEmail({}); + expect(migration710(action, context)).toMatchObject({ + ...action, + attributes: { + ...action.attributes, + config: { + hasAuth: true, + }, + }, + }); + }); + test('rename cases configuration object', () => { const migration710 = getMigrations(encryptedSavedObjectsSetup)['7.10.0']; const action = getMockData({}); @@ -36,6 +50,22 @@ describe('7.10.0', () => { }); }); +function getMockDataForEmail( + overwrites: Record = {} +): SavedObjectUnsanitizedDoc { + return { + attributes: { + name: 'abc', + actionTypeId: '.email', + config: {}, + secrets: { user: 'test', password: '123' }, + ...overwrites, + }, + id: uuid.v4(), + type: 'action', + }; +} + function getMockData( overwrites: Record = {} ): SavedObjectUnsanitizedDoc { diff --git a/x-pack/plugins/actions/server/saved_objects/migrations.ts b/x-pack/plugins/actions/server/saved_objects/migrations.ts index 0006d88c44149..993beef8d9b2b 100644 --- a/x-pack/plugins/actions/server/saved_objects/migrations.ts +++ b/x-pack/plugins/actions/server/saved_objects/migrations.ts @@ -3,40 +3,87 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - import { SavedObjectMigrationMap, SavedObjectUnsanitizedDoc, SavedObjectMigrationFn, + SavedObjectMigrationContext, } from '../../../../../src/core/server'; import { RawAction } from '../types'; import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server'; +type ActionMigration = ( + doc: SavedObjectUnsanitizedDoc +) => SavedObjectUnsanitizedDoc; + export function getMigrations( encryptedSavedObjects: EncryptedSavedObjectsPluginSetup ): SavedObjectMigrationMap { - return { '7.10.0': renameCasesConfigurationObject(encryptedSavedObjects) }; + const migrationActions = encryptedSavedObjects.createMigration( + (doc): doc is SavedObjectUnsanitizedDoc => + !!doc.attributes.config?.casesConfiguration || doc.attributes.actionTypeId === '.email', + pipeMigrations(renameCasesConfigurationObject, addHasAuthConfigurationObject) + ); + + return { + '7.10.0': executeMigrationWithErrorHandling(migrationActions, '7.10.0'), + }; } -const renameCasesConfigurationObject = ( - encryptedSavedObjects: EncryptedSavedObjectsPluginSetup -): SavedObjectMigrationFn => { - return encryptedSavedObjects.createMigration( - (doc): doc is SavedObjectUnsanitizedDoc => - !!doc.attributes.config?.casesConfiguration, - (doc: SavedObjectUnsanitizedDoc): SavedObjectUnsanitizedDoc => { - const { casesConfiguration, ...restConfiguration } = doc.attributes.config; - - return { - ...doc, - attributes: { - ...doc.attributes, - config: { - ...restConfiguration, - incidentConfiguration: casesConfiguration, - }, - }, - }; +function executeMigrationWithErrorHandling( + migrationFunc: SavedObjectMigrationFn, + version: string +) { + return (doc: SavedObjectUnsanitizedDoc, context: SavedObjectMigrationContext) => { + try { + return migrationFunc(doc, context); + } catch (ex) { + context.log.error( + `encryptedSavedObject ${version} migration failed for action ${doc.id} with error: ${ex.message}`, + { actionDocument: doc } + ); } - ); + return doc; + }; +} + +function renameCasesConfigurationObject( + doc: SavedObjectUnsanitizedDoc +): SavedObjectUnsanitizedDoc { + if (!doc.attributes.config?.casesConfiguration) { + return doc; + } + const { casesConfiguration, ...restConfiguration } = doc.attributes.config; + + return { + ...doc, + attributes: { + ...doc.attributes, + config: { + ...restConfiguration, + incidentConfiguration: casesConfiguration, + }, + }, + }; +} + +const addHasAuthConfigurationObject = ( + doc: SavedObjectUnsanitizedDoc +): SavedObjectUnsanitizedDoc => { + const hasAuth = !!doc.attributes.secrets.user || !!doc.attributes.secrets.password; + return { + ...doc, + attributes: { + ...doc.attributes, + config: { + ...doc.attributes.config, + hasAuth, + }, + }, + }; }; + +function pipeMigrations(...migrations: ActionMigration[]): ActionMigration { + return (doc: SavedObjectUnsanitizedDoc) => + migrations.reduce((migratedDoc, nextMigration) => nextMigration(migratedDoc), doc); +} diff --git a/x-pack/plugins/actions/server/usage/actions_usage_collector.ts b/x-pack/plugins/actions/server/usage/actions_usage_collector.ts index aa546e08ea1ba..fac57b6282c44 100644 --- a/x-pack/plugins/actions/server/usage/actions_usage_collector.ts +++ b/x-pack/plugins/actions/server/usage/actions_usage_collector.ts @@ -4,11 +4,26 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { MakeSchemaFrom, UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { get } from 'lodash'; import { TaskManagerStartContract } from '../../../task_manager/server'; import { ActionsUsage } from './types'; +const byTypeSchema: MakeSchemaFrom['count_by_type'] = { + // TODO: Find out an automated way to populate the keys or reformat these into an array (and change the Remote Telemetry indexer accordingly) + DYNAMIC_KEY: { type: 'long' }, + // Known actions: + __email: { type: 'long' }, + __index: { type: 'long' }, + __pagerduty: { type: 'long' }, + '__server-log': { type: 'long' }, + __slack: { type: 'long' }, + __webhook: { type: 'long' }, + __servicenow: { type: 'long' }, + __jira: { type: 'long' }, + __resilient: { type: 'long' }, +}; + export function createActionsUsageCollector( usageCollection: UsageCollectionSetup, taskManager: TaskManagerStartContract @@ -16,6 +31,12 @@ export function createActionsUsageCollector( return usageCollection.makeUsageCollector({ type: 'actions', isReady: () => true, + schema: { + count_total: { type: 'long' }, + count_active_total: { type: 'long' }, + count_by_type: byTypeSchema, + count_active_by_type: byTypeSchema, + }, fetch: async () => { try { const doc = await getLatestTaskState(await taskManager); diff --git a/x-pack/plugins/alerts/common/alert.ts b/x-pack/plugins/alerts/common/alert.ts index 3ff7ed742e810..4ebe66f7b7c9f 100644 --- a/x-pack/plugins/alerts/common/alert.ts +++ b/x-pack/plugins/alerts/common/alert.ts @@ -15,6 +15,28 @@ export interface IntervalSchedule extends SavedObjectAttributes { interval: string; } +// for the `typeof ThingValues[number]` types below, become string types that +// only accept the values in the associated string arrays +export const AlertExecutionStatusValues = ['ok', 'active', 'error', 'pending', 'unknown'] as const; +export type AlertExecutionStatuses = typeof AlertExecutionStatusValues[number]; + +export const AlertExecutionStatusErrorReasonValues = [ + 'read', + 'decrypt', + 'execute', + 'unknown', +] as const; +export type AlertExecutionStatusErrorReasons = typeof AlertExecutionStatusErrorReasonValues[number]; + +export interface AlertExecutionStatus { + status: AlertExecutionStatuses; + lastExecutionDate: Date; + error?: { + reason: AlertExecutionStatusErrorReasons; + message: string; + }; +} + export type AlertActionParams = SavedObjectAttributes; export interface AlertAction { @@ -44,6 +66,7 @@ export interface Alert { throttle: string | null; muteAll: boolean; mutedInstanceIds: string[]; + executionStatus: AlertExecutionStatus; } export type SanitizedAlert = Omit; diff --git a/x-pack/plugins/alerts/server/alerts_client.test.ts b/x-pack/plugins/alerts/server/alerts_client.test.ts index d4817eab64acb..b20018fcc26f7 100644 --- a/x-pack/plugins/alerts/server/alerts_client.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client.test.ts @@ -393,6 +393,11 @@ describe('create()', () => { "createdAt": "2019-02-12T21:01:22.479Z", "createdBy": "elastic", "enabled": true, + "executionStatus": Object { + "error": null, + "lastExecutionDate": "2019-02-12T21:01:22.479Z", + "status": "pending", + }, "meta": Object { "versionApiKeyLastmodified": "v7.10.0", }, @@ -778,8 +783,12 @@ describe('create()', () => { expect(taskManager.schedule).not.toHaveBeenCalled(); }); - test('throws error if create saved object fails', async () => { + test('throws error and invalidates API key when create saved object fails', async () => { const data = getMockData(); + alertsClientParams.createAPIKey.mockResolvedValueOnce({ + apiKeysEnabled: true, + result: { id: '123', name: '123', api_key: 'abc' }, + }); unsecuredSavedObjectsClient.bulkGet.mockResolvedValueOnce({ saved_objects: [ { @@ -798,6 +807,7 @@ describe('create()', () => { `"Test failure"` ); expect(taskManager.schedule).not.toHaveBeenCalled(); + expect(alertsClientParams.invalidateAPIKey).toHaveBeenCalledWith({ id: '123' }); }); test('attempts to remove saved object if scheduling failed', async () => { @@ -1029,6 +1039,11 @@ describe('create()', () => { muteAll: false, mutedInstanceIds: [], tags: ['foo'], + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + error: null, + }, }, { references: [ @@ -1145,6 +1160,11 @@ describe('create()', () => { muteAll: false, mutedInstanceIds: [], tags: ['foo'], + executionStatus: { + lastExecutionDate: '2019-02-12T21:01:22.479Z', + status: 'pending', + error: null, + }, }, { references: [ @@ -1422,6 +1442,10 @@ describe('enable()', () => { }); test('throws error when failing to update the first time', async () => { + alertsClientParams.createAPIKey.mockResolvedValueOnce({ + apiKeysEnabled: true, + result: { id: '123', name: '123', api_key: 'abc' }, + }); unsecuredSavedObjectsClient.update.mockReset(); unsecuredSavedObjectsClient.update.mockRejectedValueOnce(new Error('Fail to update')); @@ -1430,6 +1454,7 @@ describe('enable()', () => { ); expect(alertsClientParams.getUserName).toHaveBeenCalled(); expect(alertsClientParams.createAPIKey).toHaveBeenCalled(); + expect(alertsClientParams.invalidateAPIKey).toHaveBeenCalledWith({ id: '123' }); expect(unsecuredSavedObjectsClient.update).toHaveBeenCalledTimes(1); expect(taskManager.schedule).not.toHaveBeenCalled(); }); @@ -2496,6 +2521,11 @@ const BaseAlertInstanceSummarySavedObject: SavedObject = { throttle: null, muteAll: false, mutedInstanceIds: [], + executionStatus: { + status: 'unknown', + lastExecutionDate: '2020-08-20T19:23:38Z', + error: null, + }, }, references: [], }; @@ -3926,6 +3956,52 @@ describe('update()', () => { ); }); + test('throws when unsecuredSavedObjectsClient update fails and invalidates newly created API key', async () => { + alertsClientParams.createAPIKey.mockResolvedValueOnce({ + apiKeysEnabled: true, + result: { id: '234', name: '234', api_key: 'abc' }, + }); + unsecuredSavedObjectsClient.bulkGet.mockResolvedValueOnce({ + saved_objects: [ + { + id: '1', + type: 'action', + attributes: { + actions: [], + actionTypeId: 'test', + }, + references: [], + }, + ], + }); + unsecuredSavedObjectsClient.create.mockRejectedValue(new Error('Fail')); + await expect( + alertsClient.update({ + id: '1', + data: { + schedule: { interval: '10s' }, + name: 'abc', + tags: ['foo'], + params: { + bar: true, + }, + throttle: null, + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + }, + ], + }, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`); + expect(alertsClientParams.invalidateAPIKey).not.toHaveBeenCalledWith({ id: '123' }); + expect(alertsClientParams.invalidateAPIKey).toHaveBeenCalledWith({ id: '234' }); + }); + describe('updating an alert schedule', () => { function mockApiCalls( alertId: string, @@ -4074,14 +4150,13 @@ describe('update()', () => { expect(taskManager.runNow).not.toHaveBeenCalled(); }); - test('updating the alert should not wait for the rerun the task to complete', async (done) => { + test('updating the alert should not wait for the rerun the task to complete', async () => { const alertId = uuid.v4(); const taskId = uuid.v4(); mockApiCalls(alertId, taskId, { interval: '10s' }, { interval: '30s' }); const resolveAfterAlertUpdatedCompletes = resolvable<{ id: string }>(); - resolveAfterAlertUpdatedCompletes.then(() => done()); taskManager.runNow.mockReset(); taskManager.runNow.mockReturnValue(resolveAfterAlertUpdatedCompletes); @@ -4109,7 +4184,6 @@ describe('update()', () => { }); expect(taskManager.runNow).toHaveBeenCalled(); - resolveAfterAlertUpdatedCompletes.resolve({ id: alertId }); }); @@ -4360,13 +4434,18 @@ describe('updateApiKey()', () => { expect(alertsClientParams.invalidateAPIKey).not.toHaveBeenCalled(); }); - test('throws when unsecuredSavedObjectsClient update fails', async () => { + test('throws when unsecuredSavedObjectsClient update fails and invalidates newly created API key', async () => { + alertsClientParams.createAPIKey.mockResolvedValueOnce({ + apiKeysEnabled: true, + result: { id: '234', name: '234', api_key: 'abc' }, + }); unsecuredSavedObjectsClient.update.mockRejectedValueOnce(new Error('Fail')); await expect(alertsClient.updateApiKey({ id: '1' })).rejects.toThrowErrorMatchingInlineSnapshot( `"Fail"` ); - expect(alertsClientParams.invalidateAPIKey).not.toHaveBeenCalled(); + expect(alertsClientParams.invalidateAPIKey).not.toHaveBeenCalledWith({ id: '123' }); + expect(alertsClientParams.invalidateAPIKey).toHaveBeenCalledWith({ id: '234' }); }); describe('authorization', () => { diff --git a/x-pack/plugins/alerts/server/alerts_client.ts b/x-pack/plugins/alerts/server/alerts_client.ts index 033fdd752c695..bd278d39c6229 100644 --- a/x-pack/plugins/alerts/server/alerts_client.ts +++ b/x-pack/plugins/alerts/server/alerts_client.ts @@ -28,7 +28,7 @@ import { AlertTaskState, AlertInstanceSummary, } from './types'; -import { validateAlertTypeParams } from './lib'; +import { validateAlertTypeParams, alertExecutionStatusFromRaw } from './lib'; import { InvalidateAPIKeyParams, GrantAPIKeyResult as SecurityPluginGrantAPIKeyResult, @@ -122,6 +122,7 @@ export interface CreateOptions { | 'muteAll' | 'mutedInstanceIds' | 'actions' + | 'executionStatus' > & { actions: NormalizedAlertAction[] }; options?: { migrationVersion?: Record; @@ -228,15 +229,27 @@ export class AlertsClient { params: validatedAlertTypeParams as RawAlert['params'], muteAll: false, mutedInstanceIds: [], + executionStatus: { + status: 'pending', + lastExecutionDate: new Date().toISOString(), + error: null, + }, }; - const createdAlert = await this.unsecuredSavedObjectsClient.create( - 'alert', - this.updateMeta(rawAlert), - { - ...options, - references, - } - ); + let createdAlert: SavedObject; + try { + createdAlert = await this.unsecuredSavedObjectsClient.create( + 'alert', + this.updateMeta(rawAlert), + { + ...options, + references, + } + ); + } catch (e) { + // Avoid unused API key + this.invalidateApiKey({ apiKey: rawAlert.apiKey }); + throw e; + } if (data.enabled) { let scheduledTask; try { @@ -498,23 +511,31 @@ export class AlertsClient { : null; const apiKeyAttributes = this.apiKeyAsAlertAttributes(createdAPIKey, username); - const updatedObject = await this.unsecuredSavedObjectsClient.create( - 'alert', - this.updateMeta({ - ...attributes, - ...data, - ...apiKeyAttributes, - params: validatedAlertTypeParams as RawAlert['params'], - actions, - updatedBy: username, - }), - { - id, - overwrite: true, - version, - references, - } - ); + let updatedObject: SavedObject; + const createAttributes = this.updateMeta({ + ...attributes, + ...data, + ...apiKeyAttributes, + params: validatedAlertTypeParams as RawAlert['params'], + actions, + updatedBy: username, + }); + try { + updatedObject = await this.unsecuredSavedObjectsClient.create( + 'alert', + createAttributes, + { + id, + overwrite: true, + version, + references, + } + ); + } catch (e) { + // Avoid unused API key + this.invalidateApiKey({ apiKey: createAttributes.apiKey }); + throw e; + } return this.getPartialAlertFromRaw( id, @@ -580,19 +601,21 @@ export class AlertsClient { } const username = await this.getUserName(); - await this.unsecuredSavedObjectsClient.update( - 'alert', - id, - this.updateMeta({ - ...attributes, - ...this.apiKeyAsAlertAttributes( - await this.createAPIKey(this.generateAPIKeyName(attributes.alertTypeId, attributes.name)), - username - ), - updatedBy: username, - }), - { version } - ); + const updateAttributes = this.updateMeta({ + ...attributes, + ...this.apiKeyAsAlertAttributes( + await this.createAPIKey(this.generateAPIKeyName(attributes.alertTypeId, attributes.name)), + username + ), + updatedBy: username, + }); + try { + await this.unsecuredSavedObjectsClient.update('alert', id, updateAttributes, { version }); + } catch (e) { + // Avoid unused API key + this.invalidateApiKey({ apiKey: updateAttributes.apiKey }); + throw e; + } if (apiKeyToInvalidate) { await this.invalidateApiKey({ apiKey: apiKeyToInvalidate }); @@ -658,22 +681,22 @@ export class AlertsClient { if (attributes.enabled === false) { const username = await this.getUserName(); - await this.unsecuredSavedObjectsClient.update( - 'alert', - id, - this.updateMeta({ - ...attributes, - enabled: true, - ...this.apiKeyAsAlertAttributes( - await this.createAPIKey( - this.generateAPIKeyName(attributes.alertTypeId, attributes.name) - ), - username - ), - updatedBy: username, - }), - { version } - ); + const updateAttributes = this.updateMeta({ + ...attributes, + enabled: true, + ...this.apiKeyAsAlertAttributes( + await this.createAPIKey(this.generateAPIKeyName(attributes.alertTypeId, attributes.name)), + username + ), + updatedBy: username, + }); + try { + await this.unsecuredSavedObjectsClient.update('alert', id, updateAttributes, { version }); + } catch (e) { + // Avoid unused API key + this.invalidateApiKey({ apiKey: updateAttributes.apiKey }); + throw e; + } const scheduledTask = await this.scheduleAlert(id, attributes.alertTypeId); await this.unsecuredSavedObjectsClient.update('alert', id, { scheduledTaskId: scheduledTask.id, @@ -961,9 +984,19 @@ export class AlertsClient { updatedAt: SavedObject['updated_at'] = createdAt, references: SavedObjectReference[] | undefined ): PartialAlert { + // Not the prettiest code here, but if we want to use most of the + // alert fields from the rawAlert using `...rawAlert` kind of access, we + // need to specifically delete the executionStatus as it's a different type + // in RawAlert and Alert. Probably next time we need to do something similar + // here, we should look at redesigning the implementation of this method. + const rawAlertWithoutExecutionStatus: Partial> = { + ...rawAlert, + }; + delete rawAlertWithoutExecutionStatus.executionStatus; + const executionStatus = alertExecutionStatusFromRaw(this.logger, id, rawAlert.executionStatus); return { id, - ...rawAlert, + ...rawAlertWithoutExecutionStatus, // we currently only support the Interval Schedule type // Once we support additional types, this type signature will likely change schedule: rawAlert.schedule as IntervalSchedule, @@ -973,6 +1006,7 @@ export class AlertsClient { ...(updatedAt ? { updatedAt: new Date(updatedAt) } : {}), ...(createdAt ? { createdAt: new Date(createdAt) } : {}), ...(scheduledTaskId ? { scheduledTaskId } : {}), + ...(executionStatus ? { executionStatus } : {}), }; } diff --git a/x-pack/plugins/alerts/server/lib/alert_execution_status.test.ts b/x-pack/plugins/alerts/server/lib/alert_execution_status.test.ts new file mode 100644 index 0000000000000..3372d19cd4090 --- /dev/null +++ b/x-pack/plugins/alerts/server/lib/alert_execution_status.test.ts @@ -0,0 +1,185 @@ +/* + * 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 { loggingSystemMock } from '../../../../../src/core/server/mocks'; +import { AlertExecutionStatusErrorReasons } from '../types'; +import { + executionStatusFromState, + executionStatusFromError, + alertExecutionStatusToRaw, + alertExecutionStatusFromRaw, +} from './alert_execution_status'; +import { ErrorWithReason } from './error_with_reason'; + +const MockLogger = loggingSystemMock.create().get(); + +describe('AlertExecutionStatus', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('executionStatusFromState()', () => { + test('empty task state', () => { + const status = executionStatusFromState({}); + checkDateIsNearNow(status.lastExecutionDate); + expect(status.status).toBe('ok'); + expect(status.error).toBe(undefined); + }); + + test('task state with no instances', () => { + const status = executionStatusFromState({ alertInstances: {} }); + checkDateIsNearNow(status.lastExecutionDate); + expect(status.status).toBe('ok'); + expect(status.error).toBe(undefined); + }); + + test('task state with one instance', () => { + const status = executionStatusFromState({ alertInstances: { a: {} } }); + checkDateIsNearNow(status.lastExecutionDate); + expect(status.status).toBe('active'); + expect(status.error).toBe(undefined); + }); + }); + + describe('executionStatusFromError()', () => { + test('error with no reason', () => { + const status = executionStatusFromError(new Error('boo!')); + expect(status.status).toBe('error'); + expect(status.error).toMatchInlineSnapshot(` + Object { + "message": "boo!", + "reason": "unknown", + } + `); + }); + + test('error with a reason', () => { + const status = executionStatusFromError(new ErrorWithReason('execute', new Error('hoo!'))); + expect(status.status).toBe('error'); + expect(status.error).toMatchInlineSnapshot(` + Object { + "message": "hoo!", + "reason": "execute", + } + `); + }); + }); + + describe('alertExecutionStatusToRaw()', () => { + const date = new Date('2020-09-03T16:26:58Z'); + const status = 'ok'; + const reason: AlertExecutionStatusErrorReasons = 'decrypt'; + const error = { reason, message: 'wops' }; + + test('status without an error', () => { + expect(alertExecutionStatusToRaw({ lastExecutionDate: date, status })).toMatchInlineSnapshot(` + Object { + "error": null, + "lastExecutionDate": "2020-09-03T16:26:58.000Z", + "status": "ok", + } + `); + }); + + test('status with an error', () => { + expect(alertExecutionStatusToRaw({ lastExecutionDate: date, status, error })) + .toMatchInlineSnapshot(` + Object { + "error": Object { + "message": "wops", + "reason": "decrypt", + }, + "lastExecutionDate": "2020-09-03T16:26:58.000Z", + "status": "ok", + } + `); + }); + }); + + describe('alertExecutionStatusFromRaw()', () => { + const date = new Date('2020-09-03T16:26:58Z').toISOString(); + const status = 'active'; + const reason: AlertExecutionStatusErrorReasons = 'execute'; + const error = { reason, message: 'wops' }; + + test('no input', () => { + const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id'); + expect(result).toBe(undefined); + }); + + test('undefined input', () => { + const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', undefined); + expect(result).toBe(undefined); + }); + + test('null input', () => { + const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', null); + expect(result).toBe(undefined); + }); + + test('invalid date', () => { + const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', { + lastExecutionDate: 'an invalid date', + })!; + checkDateIsNearNow(result.lastExecutionDate); + expect(result.status).toBe('unknown'); + expect(result.error).toBe(undefined); + expect(MockLogger.debug).toBeCalledWith( + 'invalid alertExecutionStatus lastExecutionDate "an invalid date" in raw alert alert-id' + ); + }); + + test('valid date', () => { + const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', { + lastExecutionDate: date, + }); + expect(result).toMatchInlineSnapshot(` + Object { + "lastExecutionDate": 2020-09-03T16:26:58.000Z, + "status": "unknown", + } + `); + }); + + test('valid status and date', () => { + const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', { + status, + lastExecutionDate: date, + }); + expect(result).toMatchInlineSnapshot(` + Object { + "lastExecutionDate": 2020-09-03T16:26:58.000Z, + "status": "active", + } + `); + }); + + test('valid status, date and error', () => { + const result = alertExecutionStatusFromRaw(MockLogger, 'alert-id', { + status, + lastExecutionDate: date, + error, + }); + expect(result).toMatchInlineSnapshot(` + Object { + "error": Object { + "message": "wops", + "reason": "execute", + }, + "lastExecutionDate": 2020-09-03T16:26:58.000Z, + "status": "active", + } + `); + }); + }); +}); + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function checkDateIsNearNow(date: any) { + expect(date instanceof Date).toBe(true); + // allow for lots of slop in the time difference + expect(Date.now() - date.valueOf()).toBeLessThanOrEqual(10000); +} diff --git a/x-pack/plugins/alerts/server/lib/alert_execution_status.ts b/x-pack/plugins/alerts/server/lib/alert_execution_status.ts new file mode 100644 index 0000000000000..9eb0c8817f28c --- /dev/null +++ b/x-pack/plugins/alerts/server/lib/alert_execution_status.ts @@ -0,0 +1,66 @@ +/* + * 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 { Logger } from 'src/core/server'; +import { AlertTaskState, AlertExecutionStatus, RawAlertExecutionStatus } from '../types'; +import { getReasonFromError } from './error_with_reason'; + +export function executionStatusFromState(state: AlertTaskState): AlertExecutionStatus { + const instanceIds = Object.keys(state.alertInstances ?? {}); + return { + lastExecutionDate: new Date(), + status: instanceIds.length === 0 ? 'ok' : 'active', + }; +} + +export function executionStatusFromError(error: Error): AlertExecutionStatus { + return { + lastExecutionDate: new Date(), + status: 'error', + error: { + reason: getReasonFromError(error), + message: error.message, + }, + }; +} + +export function alertExecutionStatusToRaw({ + lastExecutionDate, + status, + error, +}: AlertExecutionStatus): RawAlertExecutionStatus { + return { + lastExecutionDate: lastExecutionDate.toISOString(), + status, + // explicitly setting to null (in case undefined) due to partial update concerns + error: error ?? null, + }; +} + +export function alertExecutionStatusFromRaw( + logger: Logger, + alertId: string, + rawAlertExecutionStatus?: Partial | null | undefined +): AlertExecutionStatus | undefined { + if (!rawAlertExecutionStatus) return undefined; + + const { lastExecutionDate, status = 'unknown', error } = rawAlertExecutionStatus; + + let parsedDateMillis = lastExecutionDate ? Date.parse(lastExecutionDate) : Date.now(); + if (isNaN(parsedDateMillis)) { + logger.debug( + `invalid alertExecutionStatus lastExecutionDate "${lastExecutionDate}" in raw alert ${alertId}` + ); + parsedDateMillis = Date.now(); + } + + const parsedDate = new Date(parsedDateMillis); + if (error) { + return { lastExecutionDate: parsedDate, status, error }; + } else { + return { lastExecutionDate: parsedDate, status }; + } +} diff --git a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts index b5936cf3577b3..566a1770c0658 100644 --- a/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts +++ b/x-pack/plugins/alerts/server/lib/alert_instance_summary_from_event_log.test.ts @@ -511,4 +511,8 @@ const BaseAlert: SanitizedAlert = { createdAt: new Date(), updatedAt: new Date(), apiKeyOwner: null, + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, }; diff --git a/x-pack/plugins/alerts/server/lib/error_with_reason.test.ts b/x-pack/plugins/alerts/server/lib/error_with_reason.test.ts new file mode 100644 index 0000000000000..f31f584400308 --- /dev/null +++ b/x-pack/plugins/alerts/server/lib/error_with_reason.test.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ErrorWithReason, getReasonFromError, isErrorWithReason } from './error_with_reason'; + +describe('ErrorWithReason', () => { + const plainError = new Error('well, actually'); + const errorWithReason = new ErrorWithReason('decrypt', plainError); + + test('ErrorWithReason class', () => { + expect(errorWithReason.message).toBe(plainError.message); + expect(errorWithReason.error).toBe(plainError); + expect(errorWithReason.reason).toBe('decrypt'); + }); + + test('getReasonFromError()', () => { + expect(getReasonFromError(plainError)).toBe('unknown'); + expect(getReasonFromError(errorWithReason)).toBe('decrypt'); + }); + + test('isErrorWithReason()', () => { + expect(isErrorWithReason(plainError)).toBe(false); + expect(isErrorWithReason(errorWithReason)).toBe(true); + }); +}); diff --git a/x-pack/plugins/alerts/server/lib/error_with_reason.ts b/x-pack/plugins/alerts/server/lib/error_with_reason.ts new file mode 100644 index 0000000000000..29eb666e64427 --- /dev/null +++ b/x-pack/plugins/alerts/server/lib/error_with_reason.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 { AlertExecutionStatusErrorReasons } from '../types'; + +export class ErrorWithReason extends Error { + public readonly reason: AlertExecutionStatusErrorReasons; + public readonly error: Error; + + constructor(reason: AlertExecutionStatusErrorReasons, error: Error) { + super(error.message); + this.error = error; + this.reason = reason; + } +} + +export function getReasonFromError(error: Error): AlertExecutionStatusErrorReasons { + if (isErrorWithReason(error)) { + return error.reason; + } + return 'unknown'; +} + +export function isErrorWithReason(error: Error | ErrorWithReason): error is ErrorWithReason { + return error instanceof ErrorWithReason; +} diff --git a/x-pack/plugins/alerts/server/lib/index.ts b/x-pack/plugins/alerts/server/lib/index.ts index 2f610aafd8c31..32047ae5cbfa8 100644 --- a/x-pack/plugins/alerts/server/lib/index.ts +++ b/x-pack/plugins/alerts/server/lib/index.ts @@ -7,3 +7,10 @@ export { parseDuration, validateDurationSchema } from '../../common/parse_duration'; export { LicenseState } from './license_state'; export { validateAlertTypeParams } from './validate_alert_type_params'; +export { ErrorWithReason, getReasonFromError, isErrorWithReason } from './error_with_reason'; +export { + executionStatusFromState, + executionStatusFromError, + alertExecutionStatusToRaw, + alertExecutionStatusFromRaw, +} from './alert_execution_status'; diff --git a/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.test.ts b/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.test.ts index 46ceee3ce420b..b570957d82de4 100644 --- a/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.test.ts +++ b/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.test.ts @@ -5,27 +5,27 @@ */ import { isAlertSavedObjectNotFoundError } from './is_alert_not_found_error'; +import { ErrorWithReason } from './error_with_reason'; import { SavedObjectsErrorHelpers } from '../../../../../src/core/server'; import uuid from 'uuid'; describe('isAlertSavedObjectNotFoundError', () => { + const id = uuid.v4(); + const errorSONF = SavedObjectsErrorHelpers.createGenericNotFoundError('alert', id); + test('identifies SavedObjects Not Found errors', () => { - const id = uuid.v4(); // ensure the error created by SO parses as a string with the format we expect - expect( - `${SavedObjectsErrorHelpers.createGenericNotFoundError('alert', id)}`.includes(`alert/${id}`) - ).toBe(true); - - const errorBySavedObjectsHelper = SavedObjectsErrorHelpers.createGenericNotFoundError( - 'alert', - id - ); + expect(`${errorSONF}`.includes(`alert/${id}`)).toBe(true); - expect(isAlertSavedObjectNotFoundError(errorBySavedObjectsHelper, id)).toBe(true); + expect(isAlertSavedObjectNotFoundError(errorSONF, id)).toBe(true); }); test('identifies generic errors', () => { - const id = uuid.v4(); expect(isAlertSavedObjectNotFoundError(new Error(`not found`), id)).toBe(false); }); + + test('identifies SavedObjects Not Found errors wrapped in an ErrorWithReason', () => { + const error = new ErrorWithReason('read', errorSONF); + expect(isAlertSavedObjectNotFoundError(error, id)).toBe(true); + }); }); diff --git a/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.ts b/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.ts index 0aa83ad0e883c..038e234586688 100644 --- a/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.ts +++ b/x-pack/plugins/alerts/server/lib/is_alert_not_found_error.ts @@ -5,7 +5,13 @@ */ import { SavedObjectsErrorHelpers } from '../../../../../src/core/server'; +import { isErrorWithReason } from './error_with_reason'; export function isAlertSavedObjectNotFoundError(err: Error, alertId: string) { - return SavedObjectsErrorHelpers.isNotFoundError(err) && `${err}`.includes(alertId); + // if this is an error with a reason, the actual error needs to be extracted + const actualError = isErrorWithReason(err) ? err.error : err; + + return ( + SavedObjectsErrorHelpers.isNotFoundError(actualError) && `${actualError}`.includes(alertId) + ); } diff --git a/x-pack/plugins/alerts/server/plugin.ts b/x-pack/plugins/alerts/server/plugin.ts index e9caf4b78e627..4cdcac4c9e889 100644 --- a/x-pack/plugins/alerts/server/plugin.ts +++ b/x-pack/plugins/alerts/server/plugin.ts @@ -264,6 +264,7 @@ export class AlertingPlugin { encryptedSavedObjectsClient, getBasePath: this.getBasePath, eventLogger: this.eventLogger!, + internalSavedObjectsRepository: core.savedObjects.createInternalRepository(['alert']), }); this.eventLogService!.registerSavedObjectProvider('alert', (request) => { diff --git a/x-pack/plugins/alerts/server/routes/create.test.ts b/x-pack/plugins/alerts/server/routes/create.test.ts index 274acaf01c475..51c5d2525631d 100644 --- a/x-pack/plugins/alerts/server/routes/create.test.ts +++ b/x-pack/plugins/alerts/server/routes/create.test.ts @@ -10,6 +10,7 @@ import { mockLicenseState } from '../lib/license_state.mock'; import { verifyApiAccess } from '../lib/license_api_access'; import { mockHandlerArguments } from './_mock_handler_arguments'; import { alertsClientMock } from '../alerts_client.mock'; +import { Alert } from '../../common/alert'; const alertsClient = alertsClientMock.create(); @@ -46,7 +47,7 @@ describe('createAlertRoute', () => { ], }; - const createResult = { + const createResult: Alert = { ...mockedAlert, enabled: true, muteAll: false, @@ -64,6 +65,10 @@ describe('createAlertRoute', () => { actionTypeId: 'test', }, ], + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, }; it('creates an alert with proper parameters', async () => { diff --git a/x-pack/plugins/alerts/server/routes/get.test.ts b/x-pack/plugins/alerts/server/routes/get.test.ts index 8c4b06adf70f7..c60177e90b79d 100644 --- a/x-pack/plugins/alerts/server/routes/get.test.ts +++ b/x-pack/plugins/alerts/server/routes/get.test.ts @@ -10,6 +10,7 @@ import { mockLicenseState } from '../lib/license_state.mock'; import { verifyApiAccess } from '../lib/license_api_access'; import { mockHandlerArguments } from './_mock_handler_arguments'; import { alertsClientMock } from '../alerts_client.mock'; +import { Alert } from '../../common'; const alertsClient = alertsClientMock.create(); jest.mock('../lib/license_api_access.ts', () => ({ @@ -21,7 +22,7 @@ beforeEach(() => { }); describe('getAlertRoute', () => { - const mockedAlert = { + const mockedAlert: Alert = { id: '1', alertTypeId: '1', schedule: { interval: '10s' }, @@ -51,6 +52,10 @@ describe('getAlertRoute', () => { apiKeyOwner: '', throttle: '30s', mutedInstanceIds: [], + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, }; it('gets an alert with proper parameters', async () => { diff --git a/x-pack/plugins/alerts/server/saved_objects/index.ts b/x-pack/plugins/alerts/server/saved_objects/index.ts index 51ac68b589977..9aa1f86676eaa 100644 --- a/x-pack/plugins/alerts/server/saved_objects/index.ts +++ b/x-pack/plugins/alerts/server/saved_objects/index.ts @@ -16,15 +16,19 @@ export const AlertAttributesExcludedFromAAD = [ 'muteAll', 'mutedInstanceIds', 'updatedBy', + 'executionStatus', ]; // useful for Pick which is a // type which is a subset of RawAlert with just attributes excluded from AAD + +// useful for Pick export type AlertAttributesExcludedFromAADType = | 'scheduledTaskId' | 'muteAll' | 'mutedInstanceIds' - | 'updatedBy'; + | 'updatedBy' + | 'executionStatus'; export function setupSavedObjects( savedObjects: SavedObjectsServiceSetup, @@ -42,11 +46,6 @@ export function setupSavedObjects( encryptedSavedObjects.registerType({ type: 'alert', attributesToEncrypt: new Set(['apiKey']), - attributesToExcludeFromAAD: new Set([ - 'scheduledTaskId', - 'muteAll', - 'mutedInstanceIds', - 'updatedBy', - ]), + attributesToExcludeFromAAD: new Set(AlertAttributesExcludedFromAAD), }); } diff --git a/x-pack/plugins/alerts/server/saved_objects/mappings.json b/x-pack/plugins/alerts/server/saved_objects/mappings.json index 8440b963975ff..a6c92080f18be 100644 --- a/x-pack/plugins/alerts/server/saved_objects/mappings.json +++ b/x-pack/plugins/alerts/server/saved_objects/mappings.json @@ -83,6 +83,26 @@ "type": "keyword" } } + }, + "executionStatus": { + "properties": { + "status": { + "type": "keyword" + }, + "lastExecutionDate": { + "type": "date" + }, + "error": { + "properties": { + "reason": { + "type": "keyword" + }, + "message": { + "type": "keyword" + } + } + } + } } } } diff --git a/x-pack/plugins/alerts/server/saved_objects/migrations.test.ts b/x-pack/plugins/alerts/server/saved_objects/migrations.test.ts index 10e1a9ae421b7..8c9d10769b18a 100644 --- a/x-pack/plugins/alerts/server/saved_objects/migrations.test.ts +++ b/x-pack/plugins/alerts/server/saved_objects/migrations.test.ts @@ -177,7 +177,7 @@ describe('7.10.0', () => { }, ], }); - expect(migration710(alert, { log })).toEqual({ + expect(migration710(alert, { log })).toMatchObject({ ...alert, attributes: { ...alert.attributes, @@ -199,6 +199,32 @@ describe('7.10.0', () => { }, }); }); + + test('creates execution status', () => { + const migration710 = getMigrations(encryptedSavedObjectsSetup)['7.10.0']; + const alert = getMockData(); + const dateStart = Date.now(); + const migratedAlert = migration710(alert, { log }); + const dateStop = Date.now(); + const dateExecutionStatus = Date.parse( + migratedAlert.attributes.executionStatus.lastExecutionDate + ); + + expect(dateStart).toBeLessThanOrEqual(dateExecutionStatus); + expect(dateStop).toBeGreaterThanOrEqual(dateExecutionStatus); + + expect(migratedAlert).toMatchObject({ + ...alert, + attributes: { + ...alert.attributes, + executionStatus: { + lastExecutionDate: migratedAlert.attributes.executionStatus.lastExecutionDate, + status: 'pending', + error: null, + }, + }, + }); + }); }); describe('7.10.0 migrates with failure', () => { @@ -237,7 +263,7 @@ describe('7.10.0 migrates with failure', () => { function getMockData( overwrites: Record = {} -): SavedObjectUnsanitizedDoc { +): SavedObjectUnsanitizedDoc> { return { attributes: { enabled: true, diff --git a/x-pack/plugins/alerts/server/saved_objects/migrations.ts b/x-pack/plugins/alerts/server/saved_objects/migrations.ts index 537c21e85c0bd..0b2c86b84f67b 100644 --- a/x-pack/plugins/alerts/server/saved_objects/migrations.ts +++ b/x-pack/plugins/alerts/server/saved_objects/migrations.ts @@ -30,7 +30,11 @@ export function getMigrations( // migrate all documents in 7.10 in order to add the "meta" RBAC field return true; }, - pipeMigrations(markAsLegacyAndChangeConsumer, setAlertIdAsDefaultDedupkeyOnPagerDutyActions) + pipeMigrations( + markAsLegacyAndChangeConsumer, + setAlertIdAsDefaultDedupkeyOnPagerDutyActions, + initializeExecutionStatus + ) ); return { @@ -110,6 +114,23 @@ function setAlertIdAsDefaultDedupkeyOnPagerDutyActions( }; } +function initializeExecutionStatus( + doc: SavedObjectUnsanitizedDoc +): SavedObjectUnsanitizedDoc { + const { attributes } = doc; + return { + ...doc, + attributes: { + ...attributes, + executionStatus: { + status: 'pending', + lastExecutionDate: new Date().toISOString(), + error: null, + }, + }, + }; +} + function pipeMigrations(...migrations: AlertMigration[]): AlertMigration { return (doc: SavedObjectUnsanitizedDoc) => migrations.reduce((migratedDoc, nextMigration) => nextMigration(migratedDoc), doc); diff --git a/x-pack/plugins/alerts/server/saved_objects/partially_update_alert.ts b/x-pack/plugins/alerts/server/saved_objects/partially_update_alert.ts index cc25aaba35798..b829a6788a3dd 100644 --- a/x-pack/plugins/alerts/server/saved_objects/partially_update_alert.ts +++ b/x-pack/plugins/alerts/server/saved_objects/partially_update_alert.ts @@ -15,7 +15,9 @@ import { import { AlertAttributesExcludedFromAAD, AlertAttributesExcludedFromAADType } from './index'; -export type PartiallyUpdateableAlertAttributes = Pick; +export type PartiallyUpdateableAlertAttributes = Partial< + Pick +>; export interface PartiallyUpdateAlertSavedObjectOptions { version?: string; diff --git a/x-pack/plugins/alerts/server/task_runner/alert_task_instance.test.ts b/x-pack/plugins/alerts/server/task_runner/alert_task_instance.test.ts index efac4c5dcdc01..cf0dd9d135e27 100644 --- a/x-pack/plugins/alerts/server/task_runner/alert_task_instance.test.ts +++ b/x-pack/plugins/alerts/server/task_runner/alert_task_instance.test.ts @@ -29,6 +29,10 @@ const alert: SanitizedAlert = { throttle: null, muteAll: false, mutedInstanceIds: [], + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, }; describe('Alert Task Instance', () => { diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts index 801d30b6406ee..d9af3d0ae6d5b 100644 --- a/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerts/server/task_runner/task_runner.test.ts @@ -11,14 +11,17 @@ import { ConcreteTaskInstance, TaskStatus } from '../../../task_manager/server'; import { TaskRunnerContext } from './task_runner_factory'; import { TaskRunner } from './task_runner'; import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks'; -import { loggingSystemMock } from '../../../../../src/core/server/mocks'; +import { + loggingSystemMock, + savedObjectsRepositoryMock, +} from '../../../../../src/core/server/mocks'; import { PluginStartContract as ActionsPluginStart } from '../../../actions/server'; import { actionsMock, actionsClientMock } from '../../../actions/server/mocks'; import { alertsMock, alertsClientMock } from '../mocks'; import { eventLoggerMock } from '../../../event_log/server/event_logger.mock'; import { IEventLogger } from '../../../event_log/server'; import { SavedObjectsErrorHelpers } from '../../../../../src/core/server'; - +import { Alert } from '../../common'; const alertType = { id: 'test', name: 'My test alert', @@ -71,9 +74,10 @@ describe('Task Runner', () => { spaceIdToNamespace: jest.fn().mockReturnValue(undefined), getBasePath: jest.fn().mockReturnValue(undefined), eventLogger: eventLoggerMock.create(), + internalSavedObjectsRepository: savedObjectsRepositoryMock.create(), }; - const mockedAlertTypeSavedObject = { + const mockedAlertTypeSavedObject: Alert = { id: '1', consumer: 'bar', createdAt: new Date('2019-02-12T21:01:22.479Z'), @@ -82,6 +86,7 @@ describe('Task Runner', () => { muteAll: false, enabled: true, alertTypeId: '123', + apiKey: '', apiKeyOwner: 'elastic', schedule: { interval: '10s' }, name: 'alert-name', @@ -102,6 +107,10 @@ describe('Task Runner', () => { }, }, ], + executionStatus: { + status: 'unknown', + lastExecutionDate: new Date('2020-08-20T19:23:38Z'), + }, }; beforeEach(() => { diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner.ts b/x-pack/plugins/alerts/server/task_runner/task_runner.ts index 7ea3f83d747c0..1ccf14a3a5334 100644 --- a/x-pack/plugins/alerts/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerts/server/task_runner/task_runner.ts @@ -11,7 +11,13 @@ import { ConcreteTaskInstance } from '../../../task_manager/server'; import { createExecutionHandler } from './create_execution_handler'; import { AlertInstance, createAlertInstanceFactory } from '../alert_instance'; import { getNextRunAt } from './get_next_run_at'; -import { validateAlertTypeParams } from '../lib'; +import { + validateAlertTypeParams, + executionStatusFromState, + executionStatusFromError, + alertExecutionStatusToRaw, + ErrorWithReason, +} from '../lib'; import { AlertType, RawAlert, @@ -22,6 +28,7 @@ import { Alert, AlertExecutorOptions, SanitizedAlert, + AlertExecutionStatus, } from '../types'; import { promiseResult, map, Resultable, asOk, asErr, resolveErr } from '../lib/result_type'; import { taskInstanceToAlertTaskInstance } from './alert_task_instance'; @@ -29,6 +36,7 @@ import { EVENT_LOG_ACTIONS } from '../plugin'; import { IEvent, IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '../../../event_log/server'; import { isAlertSavedObjectNotFoundError } from '../lib/is_alert_not_found_error'; import { AlertsClient } from '../alerts_client'; +import { partiallyUpdateAlert } from '../saved_objects'; const FALLBACK_RETRY_INTERVAL: IntervalSchedule = { interval: '5m' }; @@ -204,7 +212,7 @@ export class TaskRunner { event.event = event.event || {}; event.event.outcome = 'failure'; eventLogger.logEvent(event); - throw err; + throw new ErrorWithReason('execute', err); } eventLogger.stopTiming(event); @@ -278,15 +286,22 @@ export class TaskRunner { const { params: { alertId, spaceId }, } = this.taskInstance; + let apiKey: string | null; + try { + apiKey = await this.getApiKeyForAlertPermissions(alertId, spaceId); + } catch (err) { + throw new ErrorWithReason('decrypt', err); + } + const [services, alertsClient] = this.getServicesWithSpaceLevelPermissions(spaceId, apiKey); - const apiKey = await this.getApiKeyForAlertPermissions(alertId, spaceId); - const [services, alertsClient] = await this.getServicesWithSpaceLevelPermissions( - spaceId, - apiKey - ); + let alert: SanitizedAlert; // Ensure API key is still valid and user has access - const alert = await alertsClient.get({ id: alertId }); + try { + alert = await alertsClient.get({ id: alertId }); + } catch (err) { + throw new ErrorWithReason('read', err); + } return { state: await promiseResult( @@ -306,12 +321,38 @@ export class TaskRunner { async run(): Promise { const { - params: { alertId }, + params: { alertId, spaceId }, startedAt: previousStartedAt, state: originalState, } = this.taskInstance; const { state, runAt } = await errorAsAlertTaskRunResult(this.loadAlertAttributesAndRun()); + const namespace = spaceId === 'default' ? undefined : spaceId; + + const executionStatus: AlertExecutionStatus = map( + state, + (alertTaskState: AlertTaskState) => executionStatusFromState(alertTaskState), + (err: Error) => executionStatusFromError(err) + ); + this.logger.debug( + `alertExecutionStatus for ${this.alertType.id}:${alertId}: ${JSON.stringify(executionStatus)}` + ); + + const client = this.context.internalSavedObjectsRepository; + const attributes = { + executionStatus: alertExecutionStatusToRaw(executionStatus), + }; + + try { + await partiallyUpdateAlert(client, alertId, attributes, { + ignore404: true, + namespace, + }); + } catch (err) { + this.logger.error( + `error updating alert execution status for ${this.alertType.id}:${alertId} ${err.message}` + ); + } return { state: map( diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner_factory.test.ts b/x-pack/plugins/alerts/server/task_runner/task_runner_factory.test.ts index 9af7d9ddc44eb..5da8e4296f4dd 100644 --- a/x-pack/plugins/alerts/server/task_runner/task_runner_factory.test.ts +++ b/x-pack/plugins/alerts/server/task_runner/task_runner_factory.test.ts @@ -8,7 +8,10 @@ import sinon from 'sinon'; import { ConcreteTaskInstance, TaskStatus } from '../../../task_manager/server'; import { TaskRunnerContext, TaskRunnerFactory } from './task_runner_factory'; import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks'; -import { loggingSystemMock } from '../../../../../src/core/server/mocks'; +import { + loggingSystemMock, + savedObjectsRepositoryMock, +} from '../../../../../src/core/server/mocks'; import { actionsMock } from '../../../actions/server/mocks'; import { alertsMock, alertsClientMock } from '../mocks'; import { eventLoggerMock } from '../../../event_log/server/event_logger.mock'; @@ -63,6 +66,7 @@ describe('Task Runner Factory', () => { spaceIdToNamespace: jest.fn().mockReturnValue(undefined), getBasePath: jest.fn().mockReturnValue(undefined), eventLogger: eventLoggerMock.create(), + internalSavedObjectsRepository: savedObjectsRepositoryMock.create(), }; beforeEach(() => { diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner_factory.ts b/x-pack/plugins/alerts/server/task_runner/task_runner_factory.ts index 6f83e34cdbe03..944c4dc64ce7a 100644 --- a/x-pack/plugins/alerts/server/task_runner/task_runner_factory.ts +++ b/x-pack/plugins/alerts/server/task_runner/task_runner_factory.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 { Logger, KibanaRequest } from '../../../../../src/core/server'; +import { Logger, KibanaRequest, ISavedObjectsRepository } from '../../../../../src/core/server'; import { RunContext } from '../../../task_manager/server'; import { EncryptedSavedObjectsClient } from '../../../encrypted_saved_objects/server'; import { PluginStartContract as ActionsPluginStartContract } from '../../../actions/server'; @@ -26,6 +26,7 @@ export interface TaskRunnerContext { encryptedSavedObjectsClient: EncryptedSavedObjectsClient; spaceIdToNamespace: SpaceIdToNamespaceFunction; getBasePath: GetBasePathFunction; + internalSavedObjectsRepository: ISavedObjectsRepository; } export class TaskRunnerFactory { diff --git a/x-pack/plugins/alerts/server/types.ts b/x-pack/plugins/alerts/server/types.ts index 8d568e8b7ecd1..03d41724213ce 100644 --- a/x-pack/plugins/alerts/server/types.ts +++ b/x-pack/plugins/alerts/server/types.ts @@ -24,6 +24,8 @@ import { AlertTypeState, AlertInstanceContext, AlertInstanceState, + AlertExecutionStatuses, + AlertExecutionStatusErrorReasons, } from '../common'; export type WithoutQueryAndParams = Pick>; @@ -115,6 +117,18 @@ export interface AlertMeta extends SavedObjectAttributes { versionApiKeyLastmodified?: string; } +// note that the `error` property is "null-able", as we're doing a partial +// update on the alert when we update this data, but need to ensure we +// delete any previous error if the current status has no error +export interface RawAlertExecutionStatus extends SavedObjectAttributes { + status: AlertExecutionStatuses; + lastExecutionDate: string; + error: null | { + reason: AlertExecutionStatusErrorReasons; + message: string; + }; +} + export type PartialAlert = Pick & Partial>; export interface RawAlert extends SavedObjectAttributes { @@ -136,6 +150,7 @@ export interface RawAlert extends SavedObjectAttributes { muteAll: boolean; mutedInstanceIds: string[]; meta?: AlertMeta; + executionStatus: RawAlertExecutionStatus; } export type AlertInfoParams = Pick< diff --git a/x-pack/plugins/alerts/server/usage/alerts_usage_collector.ts b/x-pack/plugins/alerts/server/usage/alerts_usage_collector.ts index 64d3ad54a2318..de82dd31877af 100644 --- a/x-pack/plugins/alerts/server/usage/alerts_usage_collector.ts +++ b/x-pack/plugins/alerts/server/usage/alerts_usage_collector.ts @@ -4,11 +4,44 @@ * you may not use this file except in compliance with the Elastic License. */ -import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { MakeSchemaFrom, UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { get } from 'lodash'; import { TaskManagerStartContract } from '../../../task_manager/server'; import { AlertsUsage } from './types'; +const byTypeSchema: MakeSchemaFrom['count_by_type'] = { + // TODO: Find out an automated way to populate the keys or reformat these into an array (and change the Remote Telemetry indexer accordingly) + DYNAMIC_KEY: { type: 'long' }, + // Known alerts (searching the use of the alerts API `registerType`: + // Built-in + '__index-threshold': { type: 'long' }, + // APM + apm__error_rate: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + apm__transaction_error_rate: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + apm__transaction_duration: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + apm__transaction_duration_anomaly: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + // Infra + metrics__alert__threshold: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + metrics__alert__inventory__threshold: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + logs__alert__document__count: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + // Monitoring + monitoring_alert_cluster_health: { type: 'long' }, + monitoring_alert_cpu_usage: { type: 'long' }, + monitoring_alert_disk_usage: { type: 'long' }, + monitoring_alert_elasticsearch_version_mismatch: { type: 'long' }, + monitoring_alert_kibana_version_mismatch: { type: 'long' }, + monitoring_alert_license_expiration: { type: 'long' }, + monitoring_alert_logstash_version_mismatch: { type: 'long' }, + monitoring_alert_nodes_changed: { type: 'long' }, + // Security Solution + siem__signals: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + siem__notifications: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + // Uptime + xpack__uptime__alerts__monitorStatus: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + xpack__uptime__alerts__tls: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention + xpack__uptime__alerts__durationAnomaly: { type: 'long' }, // eslint-disable-line @typescript-eslint/naming-convention +}; + export function createAlertsUsageCollector( usageCollection: UsageCollectionSetup, taskManager: TaskManagerStartContract @@ -50,6 +83,28 @@ export function createAlertsUsageCollector( }; } }, + schema: { + count_total: { type: 'long' }, + count_active_total: { type: 'long' }, + count_disabled_total: { type: 'long' }, + throttle_time: { + min: { type: 'long' }, + avg: { type: 'float' }, + max: { type: 'long' }, + }, + schedule_time: { + min: { type: 'long' }, + avg: { type: 'float' }, + max: { type: 'long' }, + }, + connectors_per_alert: { + min: { type: 'long' }, + avg: { type: 'float' }, + max: { type: 'long' }, + }, + count_active_by_type: byTypeSchema, + count_by_type: byTypeSchema, + }, }); } diff --git a/x-pack/plugins/apm/common/__snapshots__/apm_telemetry.test.ts.snap b/x-pack/plugins/apm/common/__snapshots__/apm_telemetry.test.ts.snap index 663411dff76ff..9f7a911bf21c7 100644 --- a/x-pack/plugins/apm/common/__snapshots__/apm_telemetry.test.ts.snap +++ b/x-pack/plugins/apm/common/__snapshots__/apm_telemetry.test.ts.snap @@ -11,6 +11,67 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "apm": { "properties": { + "services_per_agent": { + "properties": { + "dotnet": { + "type": "long" + }, + "go": { + "type": "long" + }, + "java": { + "type": "long" + }, + "js-base": { + "type": "long" + }, + "nodejs": { + "type": "long" + }, + "python": { + "type": "long" + }, + "ruby": { + "type": "long" + }, + "rum-js": { + "type": "long" + }, + "otlp": { + "type": "long" + }, + "opentelemetry/cpp": { + "type": "long" + }, + "opentelemetry/dotnet": { + "type": "long" + }, + "opentelemetry/erlang": { + "type": "long" + }, + "opentelemetry/go": { + "type": "long" + }, + "opentelemetry/java": { + "type": "long" + }, + "opentelemetry/nodejs": { + "type": "long" + }, + "opentelemetry/php": { + "type": "long" + }, + "opentelemetry/python": { + "type": "long" + }, + "opentelemetry/ruby": { + "type": "long" + }, + "opentelemetry/webjs": { + "type": "long" + } + } + }, "agents": { "properties": { "dotnet": { @@ -18,8 +79,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -27,49 +87,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -82,8 +133,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -91,49 +141,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -146,8 +187,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -155,49 +195,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -210,8 +241,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -219,49 +249,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -274,8 +295,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -283,49 +303,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -338,8 +349,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -347,49 +357,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -402,8 +403,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -411,49 +411,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -466,8 +457,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -475,49 +465,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -530,8 +511,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -539,49 +519,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -594,8 +565,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -603,49 +573,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -658,8 +619,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -667,49 +627,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -722,8 +673,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -731,49 +681,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -786,8 +727,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -795,49 +735,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -850,8 +781,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -859,49 +789,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -914,8 +835,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -923,49 +843,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -978,8 +889,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -987,49 +897,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -1042,8 +943,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -1051,49 +951,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 - } + "type": "keyword" + }, + "composite": { + "type": "keyword" + } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -1106,8 +997,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -1115,49 +1005,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -1170,8 +1051,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "agent": { "properties": { "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, @@ -1179,49 +1059,40 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "framework": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "language": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } }, "runtime": { "properties": { - "composite": { - "type": "keyword", - "ignore_above": 1024 - }, "name": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "version": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" + }, + "composite": { + "type": "keyword" } } } @@ -1231,6 +1102,39 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, + "has_any_services": { + "type": "boolean" + }, + "version": { + "properties": { + "apm_server": { + "properties": { + "major": { + "type": "long" + }, + "minor": { + "type": "long" + }, + "patch": { + "type": "long" + } + } + } + } + }, + "environments": { + "properties": { + "services_without_environments": { + "type": "long" + }, + "services_with_multiple_environments": { + "type": "long" + }, + "top_environments": { + "type": "keyword" + } + } + }, "aggregated_transactions": { "properties": { "current_implementation": { @@ -1240,9 +1144,6 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the }, "transaction_count": { "type": "long" - }, - "ratio": { - "type": "float" } } }, @@ -1253,67 +1154,77 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the }, "transaction_count": { "type": "long" - }, - "ratio": { - "type": "float" } } }, - "with_country": { + "no_rum": { "properties": { "expected_metric_document_count": { "type": "long" }, "transaction_count": { "type": "long" + } + } + }, + "no_rum_no_observer_name": { + "properties": { + "expected_metric_document_count": { + "type": "long" }, - "ratio": { - "type": "float" + "transaction_count": { + "type": "long" } } - } - } - }, - "environments": { - "properties": { - "services_without_environment": { - "type": "long" }, - "services_with_multiple_environments": { - "type": "long" + "only_rum": { + "properties": { + "expected_metric_document_count": { + "type": "long" + }, + "transaction_count": { + "type": "long" + } + } }, - "top_enviroments": { - "type": "keyword", - "ignore_above": 1024 + "only_rum_no_observer_name": { + "properties": { + "expected_metric_document_count": { + "type": "long" + }, + "transaction_count": { + "type": "long" + } + } } } }, "cloud": { "properties": { "availability_zone": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "provider": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" }, "region": { - "type": "keyword", - "ignore_above": 1024 + "type": "keyword" } } }, "counts": { "properties": { - "agent_configuration": { + "transaction": { "properties": { + "1d": { + "type": "long" + }, "all": { "type": "long" } } }, - "error": { + "span": { "properties": { "1d": { "type": "long" @@ -1323,21 +1234,27 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "max_error_groups_per_service": { + "error": { "properties": { "1d": { "type": "long" + }, + "all": { + "type": "long" } } }, - "max_transaction_groups_per_service": { + "metric": { "properties": { "1d": { "type": "long" + }, + "all": { + "type": "long" } } }, - "metric": { + "sourcemap": { "properties": { "1d": { "type": "long" @@ -1357,14 +1274,14 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "services": { + "agent_configuration": { "properties": { - "1d": { + "all": { "type": "long" } } }, - "sourcemap": { + "max_transaction_groups_per_service": { "properties": { "1d": { "type": "long" @@ -1374,7 +1291,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "span": { + "max_error_groups_per_service": { "properties": { "1d": { "type": "long" @@ -1388,10 +1305,13 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the "properties": { "1d": { "type": "long" + }, + "all": { + "type": "long" } } }, - "transaction": { + "services": { "properties": { "1d": { "type": "long" @@ -1470,55 +1390,22 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "has_any_services": { - "type": "boolean" - }, - "indices": { + "retainment": { "properties": { - "all": { - "properties": { - "total": { - "properties": { - "docs": { - "properties": { - "count": { - "type": "long" - } - } - }, - "store": { - "properties": { - "size_in_bytes": { - "type": "long" - } - } - } - } - } - } - }, - "shards": { + "span": { "properties": { - "total": { + "ms": { "type": "long" } } - } - } - }, - "integrations": { - "properties": { - "ml": { + }, + "transaction": { "properties": { - "all_jobs_count": { + "ms": { "type": "long" } } - } - } - }, - "retainment": { - "properties": { + }, "error": { "properties": { "ms": { @@ -1533,106 +1420,63 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "onboarding": { + "sourcemap": { "properties": { "ms": { "type": "long" } } }, - "span": { + "onboarding": { "properties": { "ms": { "type": "long" } } - }, - "transaction": { + } + } + }, + "integrations": { + "properties": { + "ml": { "properties": { - "ms": { + "all_jobs_count": { "type": "long" } } } } }, - "services_per_agent": { + "indices": { "properties": { - "dotnet": { - "type": "long", - "null_value": 0 - }, - "go": { - "type": "long", - "null_value": 0 - }, - "java": { - "type": "long", - "null_value": 0 - }, - "js-base": { - "type": "long", - "null_value": 0 - }, - "nodejs": { - "type": "long", - "null_value": 0 - }, - "python": { - "type": "long", - "null_value": 0 - }, - "ruby": { - "type": "long", - "null_value": 0 - }, - "rum-js": { - "type": "long", - "null_value": 0 - }, - "otlp": { - "type": "long", - "null_value": 0 - }, - "opentelemetry/cpp": { - "type": "long", - "null_value": 0 - }, - "opentelemetry/dotnet": { - "type": "long", - "null_value": 0 - }, - "opentelemetry/erlang": { - "type": "long", - "null_value": 0 - }, - "opentelemetry/go": { - "type": "long", - "null_value": 0 - }, - "opentelemetry/java": { - "type": "long", - "null_value": 0 - }, - "opentelemetry/nodejs": { - "type": "long", - "null_value": 0 - }, - "opentelemetry/php": { - "type": "long", - "null_value": 0 - }, - "opentelemetry/python": { - "type": "long", - "null_value": 0 - }, - "opentelemetry/ruby": { - "type": "long", - "null_value": 0 + "shards": { + "properties": { + "total": { + "type": "long" + } + } }, - "opentelemetry/webjs": { - "type": "long", - "null_value": 0 + "all": { + "properties": { + "total": { + "properties": { + "docs": { + "properties": { + "count": { + "type": "long" + } + } + }, + "store": { + "properties": { + "size_in_bytes": { + "type": "long" + } + } + } + } + } + } } } }, @@ -1649,7 +1493,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "agent_configuration": { + "cloud": { "properties": { "took": { "properties": { @@ -1660,7 +1504,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "agents": { + "processor_events": { "properties": { "took": { "properties": { @@ -1671,7 +1515,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "cardinality": { + "agent_configuration": { "properties": { "took": { "properties": { @@ -1682,7 +1526,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "cloud": { + "services": { "properties": { "took": { "properties": { @@ -1693,7 +1537,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "environments": { + "versions": { "properties": { "took": { "properties": { @@ -1715,17 +1559,6 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "indices_stats": { - "properties": { - "took": { - "properties": { - "ms": { - "type": "long" - } - } - } - } - }, "integrations": { "properties": { "took": { @@ -1737,7 +1570,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "processor_events": { + "agents": { "properties": { "took": { "properties": { @@ -1748,7 +1581,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "services": { + "indices_stats": { "properties": { "took": { "properties": { @@ -1759,7 +1592,7 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } }, - "versions": { + "cardinality": { "properties": { "took": { "properties": { @@ -1771,23 +1604,6 @@ exports[`APM telemetry helpers getApmTelemetry generates a JSON object with the } } } - }, - "version": { - "properties": { - "apm_server": { - "properties": { - "major": { - "type": "long" - }, - "minor": { - "type": "long" - }, - "patch": { - "type": "long" - } - } - } - } } } } diff --git a/x-pack/plugins/apm/common/apm_telemetry.ts b/x-pack/plugins/apm/common/apm_telemetry.ts index 874cee05553d4..faf5b21d69c7b 100644 --- a/x-pack/plugins/apm/common/apm_telemetry.ts +++ b/x-pack/plugins/apm/common/apm_telemetry.ts @@ -4,260 +4,39 @@ * you may not use this file except in compliance with the Elastic License. */ import { produce } from 'immer'; -import { AGENT_NAMES } from './agent_name'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { apmSchema } from '../server/lib/apm_telemetry/schema'; + +function schemaToMapping(schemaLeaf: any): any { + // convert "array" definition to mapping + if (schemaLeaf.type === 'array') { + return schemaToMapping(schemaLeaf.items); + } + + if (typeof schemaLeaf.type === 'string') { + return schemaLeaf; + } + + return Object.entries(schemaLeaf).reduce((acc, [key, value]) => { + const propMapping = schemaToMapping(value); + + return { + ...acc, + [key]: + typeof propMapping.type === 'string' + ? propMapping + : { properties: propMapping }, + }; + }, {}); +} /** - * Generate an object containing the mapping used for APM telemetry. Can be used - * with the `upload-telemetry-data` script or to update the mapping in the - * telemetry repository. - * - * This function breaks things up to make the mapping easier to understand. + * Generate an object containing the mapping used for APM telemetry based on the schema specified + * in the usage collector. Can be used with the `upload-telemetry-data` script or to update the + * mapping in the telemetry repository. */ export function getApmTelemetryMapping() { - const keyword = { - type: 'keyword', - ignore_above: 1024, - }; - - const float = { - type: 'float', - }; - - const long = { - type: 'long', - }; - - const allProperties = { - properties: { - all: long, - }, - }; - - const oneDayProperties = { - properties: { - '1d': long, - }, - }; - - const oneDayAllProperties = { - properties: { - '1d': long, - all: long, - }, - }; - - const msProperties = { - properties: { - ms: long, - }, - }; - - const tookProperties = { - properties: { - took: msProperties, - }, - }; - - const compositeNameVersionProperties = { - properties: { - composite: keyword, - name: keyword, - version: keyword, - }, - }; - - const agentProperties = { - properties: { version: keyword }, - }; - - const serviceProperties = { - properties: { - framework: compositeNameVersionProperties, - language: compositeNameVersionProperties, - runtime: compositeNameVersionProperties, - }, - }; - - const aggregatedTransactionsProperties = { - properties: { - expected_metric_document_count: long, - transaction_count: long, - ratio: float, - }, - }; - - return { - properties: { - agents: { - properties: AGENT_NAMES.reduce>( - (previousValue, currentValue) => { - previousValue[currentValue] = { - properties: { - agent: agentProperties, - service: serviceProperties, - }, - }; - - return previousValue; - }, - {} - ), - }, - aggregated_transactions: { - properties: { - current_implementation: aggregatedTransactionsProperties, - no_observer_name: aggregatedTransactionsProperties, - with_country: aggregatedTransactionsProperties, - }, - }, - environments: { - properties: { - services_without_environment: long, - services_with_multiple_environments: long, - top_enviroments: keyword, - }, - }, - cloud: { - properties: { - availability_zone: keyword, - provider: keyword, - region: keyword, - }, - }, - counts: { - properties: { - agent_configuration: allProperties, - error: oneDayAllProperties, - max_error_groups_per_service: oneDayProperties, - max_transaction_groups_per_service: oneDayProperties, - metric: oneDayAllProperties, - onboarding: oneDayAllProperties, - services: oneDayProperties, - sourcemap: oneDayAllProperties, - span: oneDayAllProperties, - traces: oneDayProperties, - transaction: oneDayAllProperties, - }, - }, - cardinality: { - properties: { - client: { - properties: { - geo: { - properties: { - country_iso_code: { properties: { rum: oneDayProperties } }, - }, - }, - }, - }, - user_agent: { - properties: { - original: { - properties: { - all_agents: oneDayProperties, - rum: oneDayProperties, - }, - }, - }, - }, - transaction: { - properties: { - name: { - properties: { - all_agents: oneDayProperties, - rum: oneDayProperties, - }, - }, - }, - }, - }, - }, - has_any_services: { - type: 'boolean', - }, - indices: { - properties: { - all: { - properties: { - total: { - properties: { - docs: { - properties: { - count: long, - }, - }, - store: { - properties: { - size_in_bytes: long, - }, - }, - }, - }, - }, - }, - shards: { - properties: { - total: long, - }, - }, - }, - }, - integrations: { - properties: { - ml: { - properties: { - all_jobs_count: long, - }, - }, - }, - }, - retainment: { - properties: { - error: msProperties, - metric: msProperties, - onboarding: msProperties, - span: msProperties, - transaction: msProperties, - }, - }, - services_per_agent: { - properties: AGENT_NAMES.reduce>( - (previousValue, currentValue) => { - previousValue[currentValue] = { ...long, null_value: 0 }; - return previousValue; - }, - {} - ), - }, - tasks: { - properties: { - aggregated_transactions: tookProperties, - agent_configuration: tookProperties, - agents: tookProperties, - cardinality: tookProperties, - cloud: tookProperties, - environments: tookProperties, - groupings: tookProperties, - indices_stats: tookProperties, - integrations: tookProperties, - processor_events: tookProperties, - services: tookProperties, - versions: tookProperties, - }, - }, - version: { - properties: { - apm_server: { - properties: { - major: long, - minor: long, - patch: long, - }, - }, - }, - }, - }, - }; + return { properties: schemaToMapping(apmSchema) }; } /** diff --git a/x-pack/plugins/apm/common/service_health_status.ts b/x-pack/plugins/apm/common/service_health_status.ts index 1d4bcfb3b0e07..f66e03a9733a3 100644 --- a/x-pack/plugins/apm/common/service_health_status.ts +++ b/x-pack/plugins/apm/common/service_health_status.ts @@ -54,6 +54,22 @@ export function getServiceHealthStatusColor( } } +export function getServiceHealthStatusBadgeColor( + theme: EuiTheme, + status: ServiceHealthStatus +) { + switch (status) { + case ServiceHealthStatus.healthy: + return theme.eui.euiColorVis0_behindText; + case ServiceHealthStatus.warning: + return theme.eui.euiColorVis5_behindText; + case ServiceHealthStatus.critical: + return theme.eui.euiColorVis9_behindText; + case ServiceHealthStatus.unknown: + return theme.eui.euiColorMediumShade; + } +} + export function getServiceHealthStatusLabel(status: ServiceHealthStatus) { switch (status) { case ServiceHealthStatus.critical: diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/breakdown_filter.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/breakdown_filter.ts index acfbe6e0a4e78..342f3e0aa5267 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/breakdown_filter.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/breakdown_filter.ts @@ -36,7 +36,7 @@ Then(`breakdown series should appear in chart`, () => { cy.get('div.echLegendItem__label', DEFAULT_TIMEOUT).should( 'have.text', - 'ChromeChrome Mobile WebViewSafariFirefoxMobile SafariChrome MobileChrome Mobile iOSOverall' + 'OverallChromeChrome Mobile WebViewSafariFirefoxMobile SafariChrome MobileChrome Mobile iOS' ); }); }); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts index 28af4fd5d8a56..a8edf862ab256 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_dashboard.ts @@ -26,7 +26,7 @@ Given(`a user browses the APM UI application for RUM Data`, () => { }); Then(`should have correct client metrics`, () => { - const metrics = ['4 ms', '0.06 s', '55 ']; + const metrics = ['4 ms', '58 ms', '55']; verifyClientMetrics(metrics, true); }); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts index 75974ef9c202c..5c2109bb518c2 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/csm_filters.ts @@ -56,7 +56,7 @@ Then(/^it filters the client metrics "([^"]*)"$/, (filterName) => { cy.get('.euiStat__title-isLoading').should('not.be.visible'); const data = - filterName === 'os' ? ['5 ms', '0.06 s', '8 '] : ['4 ms', '0.05 s', '28 ']; + filterName === 'os' ? ['5 ms', '64 ms', '8'] : ['4 ms', '55 ms', '28']; verifyClientMetrics(data, true); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts index 4d2ba4d01ae6c..55c980d5edeb4 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/percentile_select.ts @@ -18,7 +18,7 @@ When('the user changes the selected percentile', () => { }); Then(`it displays client metric related to that percentile`, () => { - const metrics = ['14 ms', '0.13 s', '55 ']; + const metrics = ['14 ms', '131 ms', '55']; verifyClientMetrics(metrics, false); diff --git a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts index b3899a5649b72..20c6a3fb72aa9 100644 --- a/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts +++ b/x-pack/plugins/apm/e2e/cypress/support/step_definitions/csm/service_name_filter.ts @@ -15,7 +15,7 @@ When('the user changes the selected service name', () => { }); Then(`it displays relevant client metrics`, () => { - const metrics = ['4 ms', '0.06 s', '55 ']; + const metrics = ['4 ms', '58 ms', '55']; verifyClientMetrics(metrics, false); }); diff --git a/x-pack/plugins/apm/e2e/package.json b/x-pack/plugins/apm/e2e/package.json index 649198b7eae11..041f9ea7f21c0 100644 --- a/x-pack/plugins/apm/e2e/package.json +++ b/x-pack/plugins/apm/e2e/package.json @@ -14,7 +14,7 @@ "@types/node": ">=10.17.17 <10.20.0", "axios": "^0.19.2", "cypress-cucumber-preprocessor": "^2.5.2", - "cypress": "^4.9.0", + "cypress": "^5.0.0", "ora": "^4.0.4", "p-limit": "^3.0.1", "p-retry": "^4.2.0", diff --git a/x-pack/plugins/apm/public/application/csmApp.tsx b/x-pack/plugins/apm/public/application/csmApp.tsx index 5ebe14b663f56..2baddbe572a52 100644 --- a/x-pack/plugins/apm/public/application/csmApp.tsx +++ b/x-pack/plugins/apm/public/application/csmApp.tsx @@ -22,7 +22,6 @@ import { renderAsRedirectTo } from '../components/app/Main/route_config'; import { ScrollToTopOnPathChange } from '../components/app/Main/ScrollToTopOnPathChange'; import { RumHome, UX_LABEL } from '../components/app/RumDashboard/RumHome'; import { ApmPluginContext } from '../context/ApmPluginContext'; -import { LoadingIndicatorProvider } from '../context/LoadingIndicatorContext'; import { UrlParamsProvider } from '../context/UrlParamsContext'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; import { ConfigSchema } from '../index'; @@ -92,9 +91,7 @@ export function CsmAppRoot({ - - - + diff --git a/x-pack/plugins/apm/public/application/index.tsx b/x-pack/plugins/apm/public/application/index.tsx index 9843f73dafdbb..24505951c9d71 100644 --- a/x-pack/plugins/apm/public/application/index.tsx +++ b/x-pack/plugins/apm/public/application/index.tsx @@ -24,7 +24,6 @@ import { routes } from '../components/app/Main/route_config'; import { ScrollToTopOnPathChange } from '../components/app/Main/ScrollToTopOnPathChange'; import { ApmPluginContext } from '../context/ApmPluginContext'; import { LicenseProvider } from '../context/LicenseContext'; -import { LoadingIndicatorProvider } from '../context/LoadingIndicatorContext'; import { UrlParamsProvider } from '../context/UrlParamsContext'; import { useBreadcrumbs } from '../hooks/use_breadcrumbs'; import { ApmPluginSetupDeps } from '../plugin'; @@ -99,11 +98,9 @@ export function ApmAppRoot({ - - - - - + + + diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx index 4a5f43dacedf4..4eb24f8c80b9a 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/Charts/PageLoadDistChart.tsx @@ -88,6 +88,10 @@ export function PageLoadDistChart({ const [darkMode] = useUiSetting$('theme:darkMode'); + const euiChartTheme = darkMode + ? EUI_CHARTS_THEME_DARK + : EUI_CHARTS_THEME_LIGHT; + return ( numeral(d).format('0.0') + '%'} + labelFormat={(d) => d + ' %'} /> numeral(d).format('0.0') + ' %'} /> {breakdown && ( ('theme:darkMode'); @@ -83,17 +85,17 @@ export function PageViewsChart({ data, loading }: Props) { return yAccessor; }; + const euiChartTheme = darkMode + ? EUI_CHARTS_THEME_DARK + : EUI_CHARTS_THEME_LIGHT; + return ( {(!loading || data) && ( )} diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx index 03f2f31f35817..310c01291aea4 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/ClientMetrics/index.tsx @@ -11,6 +11,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiStat, EuiToolTip } from '@elastic/eui'; import { useFetcher } from '../../../../hooks/useFetcher'; import { I18LABELS } from '../translations'; import { useUxQuery } from '../hooks/useUxQuery'; +import { formatToSec } from '../UXMetrics/KeyUXMetrics'; import { CsmSharedContext } from '../CsmSharedContext'; const ClFlexGroup = styled(EuiFlexGroup)` @@ -49,14 +50,14 @@ export function ClientMetrics() { const STAT_STYLE = { width: '240px' }; + const pageViewsTotal = data?.pageViews?.value ?? 0; + return ( @@ -64,7 +65,7 @@ export function ClientMetrics() { @@ -73,9 +74,13 @@ export function ClientMetrics() { - <>{numeral(data?.pageViews?.value).format('0 a') ?? '-'} - + pageViewsTotal < 10000 ? ( + numeral(pageViewsTotal).format('0,0') + ) : ( + + <>{numeral(pageViewsTotal).format('0 a')} + + ) } description={I18LABELS.pageViews} isLoading={status !== 'success'} diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/BreakdownSeries.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/BreakdownSeries.tsx index 3463327441b7b..f348aca495c71 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/BreakdownSeries.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/PageLoadDistribution/BreakdownSeries.tsx @@ -6,8 +6,13 @@ import { CurveType, Fit, LineSeries, ScaleType } from '@elastic/charts'; import React, { useEffect } from 'react'; +import { + EUI_CHARTS_THEME_DARK, + EUI_CHARTS_THEME_LIGHT, +} from '@elastic/eui/dist/eui_charts_theme'; import { PercentileRange } from './index'; import { useBreakdowns } from './use_breakdowns'; +import { useUiSetting$ } from '../../../../../../../../src/plugins/kibana_react/public'; interface Props { field: string; @@ -22,6 +27,12 @@ export function BreakdownSeries({ percentileRange, onLoadingChange, }: Props) { + const [darkMode] = useUiSetting$('theme:darkMode'); + + const euiChartTheme = darkMode + ? EUI_CHARTS_THEME_DARK + : EUI_CHARTS_THEME_LIGHT; + const { data, status } = useBreakdowns({ field, value, @@ -32,9 +43,11 @@ export function BreakdownSeries({ onLoadingChange(status !== 'success'); }, [status, onLoadingChange]); + // sort index 1 color vizColors1 is already used for overall, + // so don't user that here return ( <> - {data?.map(({ data: seriesData, name }) => ( + {data?.map(({ data: seriesData, name }, sortIndex) => ( ))} diff --git a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx index 53722658cafef..5b0e9709d4fa3 100644 --- a/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx +++ b/x-pack/plugins/apm/public/components/app/RumDashboard/UXMetrics/KeyUXMetrics.tsx @@ -6,6 +6,7 @@ import React from 'react'; import { EuiFlexItem, EuiStat, EuiFlexGroup } from '@elastic/eui'; +import numeral from '@elastic/numeral'; import { UXMetrics } from './index'; import { FCP_LABEL, @@ -77,7 +78,7 @@ export function KeyUXMetrics({ data, loading }: Props) { diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/LoadingOverlay.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/LoadingOverlay.tsx deleted file mode 100644 index 8557c3f0c0798..0000000000000 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/LoadingOverlay.tsx +++ /dev/null @@ -1,61 +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 { EuiProgress, EuiText, EuiSpacer } from '@elastic/eui'; -import styled from 'styled-components'; -import { i18n } from '@kbn/i18n'; - -const Container = styled.div` - position: relative; -`; - -const Overlay = styled.div` - position: absolute; - top: 0; - z-index: 1; - display: flex; - flex-direction: column; - align-items: center; - width: 100%; - padding: ${({ theme }) => theme.eui.gutterTypes.gutterMedium}; -`; - -const ProgressBarContainer = styled.div` - width: 50%; - max-width: 600px; -`; - -interface Props { - isLoading: boolean; - percentageLoaded: number; -} - -export function LoadingOverlay({ isLoading, percentageLoaded }: Props) { - return ( - - {isLoading && ( - - - - - - - {i18n.translate('xpack.apm.loadingServiceMap', { - defaultMessage: - 'Loading service map... This might take a short while.', - })} - - - )} - - ); -} diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/example_response_opbeans_beats.json b/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/example_response_opbeans_beats.json index 153fa57bb05e7..cfd905f145fe2 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/example_response_opbeans_beats.json +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/__stories__/example_response_opbeans_beats.json @@ -83,7 +83,7 @@ "id": "opbeans-go~>postgresql", "sourceData": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go" }, @@ -103,7 +103,7 @@ "id": "opbeans-go~opbeans-java", "sourceData": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go" }, @@ -123,13 +123,13 @@ "id": "opbeans-go~opbeans-node", "sourceData": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go" }, "targetData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" }, @@ -143,7 +143,7 @@ "id": "opbeans-go~opbeans-ruby", "sourceData": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go" }, @@ -189,7 +189,7 @@ }, "targetData": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go" }, @@ -209,7 +209,7 @@ }, "targetData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" } @@ -242,7 +242,7 @@ "id": "opbeans-node~>postgresql", "sourceData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" }, @@ -262,7 +262,7 @@ "id": "opbeans-node~>redis", "sourceData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" }, @@ -282,13 +282,13 @@ "id": "opbeans-node~opbeans-go", "sourceData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" }, "targetData": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go" }, @@ -302,7 +302,7 @@ "id": "opbeans-node~opbeans-python", "sourceData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" }, @@ -322,7 +322,7 @@ "id": "opbeans-node~opbeans-ruby", "sourceData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" }, @@ -408,7 +408,7 @@ }, "targetData": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go" } @@ -427,7 +427,7 @@ }, "targetData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" }, @@ -487,7 +487,7 @@ }, "targetData": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go" }, @@ -527,7 +527,7 @@ }, "targetData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" }, @@ -566,7 +566,7 @@ }, "targetData": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go" } @@ -602,7 +602,7 @@ }, "targetData": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" } @@ -673,7 +673,7 @@ { "data": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs", "anomaly_score": 41.31593099784474, @@ -733,7 +733,7 @@ { "data": { "id": "opbeans-go", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-go", "agent.name": "go", "anomaly_score": 0.2633884161762746, diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/HealthBadge.tsx b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/HealthBadge.tsx index c6be0a352ef66..e8ad3e65b1a47 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/HealthBadge.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/HealthBadge.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { EuiBadge } from '@elastic/eui'; import { - getServiceHealthStatusColor, + getServiceHealthStatusBadgeColor, getServiceHealthStatusLabel, ServiceHealthStatus, } from '../../../../../common/service_health_status'; @@ -20,7 +20,7 @@ export function HealthBadge({ const theme = useTheme(); return ( - + {getServiceHealthStatusLabel(healthStatus)} ); diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap index 40a2b6a5fa81b..ee3a4fce0dbaa 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap @@ -153,7 +153,7 @@ NodeList [ > { - it('should not flicker between show/hide when the hide interval is very short', async () => { - jest.useFakeTimers(); - const visibilityChanges: boolean[] = []; - const advanceTimer = new AdvanceTimer(); - const delayed = new Delayed(); - - delayed.onChange((isVisible) => visibilityChanges.push(isVisible)); - - for (let i = 1; i < 100; i += 2) { - delayed.show(); - advanceTimer.advance(1000); - delayed.hide(); - advanceTimer.advance(20); - } - advanceTimer.advance(100); - - expect(visibilityChanges).toEqual([true, false]); - }); - - it('should not be shown at all when the duration is very short', async () => { - jest.useFakeTimers(); - const advanceTimer = new AdvanceTimer(); - const visibilityChanges: boolean[] = []; - const delayed = new Delayed(); - - delayed.onChange((isVisible) => visibilityChanges.push(isVisible)); - - delayed.show(); - advanceTimer.advance(30); - delayed.hide(); - advanceTimer.advance(1000); - - expect(visibilityChanges).toEqual([]); - }); - - it('should be displayed for minimum 1000ms', async () => { - jest.useFakeTimers(); - const visibilityChanges: boolean[] = []; - const advanceTimer = new AdvanceTimer(); - const delayed = new Delayed(); - - delayed.onChange((isVisible) => visibilityChanges.push(isVisible)); - - delayed.show(); - advanceTimer.advance(200); - delayed.hide(); - advanceTimer.advance(950); - expect(visibilityChanges).toEqual([true]); - advanceTimer.advance(100); - expect(visibilityChanges).toEqual([true, false]); - delayed.show(); - advanceTimer.advance(50); - expect(visibilityChanges).toEqual([true, false, true]); - delayed.hide(); - advanceTimer.advance(950); - expect(visibilityChanges).toEqual([true, false, true]); - advanceTimer.advance(100); - expect(visibilityChanges).toEqual([true, false, true, false]); - }); - - it('should be displayed for minimum 2000ms', async () => { - jest.useFakeTimers(); - const visibilityChanges: boolean[] = []; - const advanceTimer = new AdvanceTimer(); - const delayed = new Delayed({ minimumVisibleDuration: 2000 }); - - delayed.onChange((isVisible) => visibilityChanges.push(isVisible)); - - delayed.show(); - advanceTimer.advance(200); - delayed.hide(); - advanceTimer.advance(1950); - expect(visibilityChanges).toEqual([true]); - advanceTimer.advance(100); - expect(visibilityChanges).toEqual([true, false]); - }); -}); diff --git a/x-pack/plugins/apm/public/components/shared/useDelayedVisibility/Delayed/index.ts b/x-pack/plugins/apm/public/components/shared/useDelayedVisibility/Delayed/index.ts deleted file mode 100644 index daab721f64b1a..0000000000000 --- a/x-pack/plugins/apm/public/components/shared/useDelayedVisibility/Delayed/index.ts +++ /dev/null @@ -1,66 +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. - */ - -type Callback = (isVisible: boolean) => void; - -export class Delayed { - private displayedAt = 0; - private hideDelayMs: number; - private isVisible = false; - private minimumVisibleDuration: number; - private showDelayMs: number; - private timeoutId?: number; - - constructor({ - minimumVisibleDuration = 1000, - showDelayMs = 50, - hideDelayMs = 50, - } = {}) { - this.minimumVisibleDuration = minimumVisibleDuration; - this.hideDelayMs = hideDelayMs; - this.showDelayMs = showDelayMs; - } - - private onChangeCallback: Callback = () => null; - - private updateState(isVisible: boolean) { - window.clearTimeout(this.timeoutId); - const ms = !isVisible - ? Math.max( - this.displayedAt + this.minimumVisibleDuration - Date.now(), - this.hideDelayMs - ) - : this.showDelayMs; - - this.timeoutId = window.setTimeout(() => { - if (this.isVisible !== isVisible) { - this.isVisible = isVisible; - this.onChangeCallback(isVisible); - if (isVisible) { - this.displayedAt = Date.now(); - } - } - }, ms); - } - - public show() { - this.updateState(true); - } - - public hide() { - this.updateState(false); - } - - public onChange(onChangeCallback: Callback) { - this.onChangeCallback = onChangeCallback; - } - - public destroy() { - if (this.timeoutId) { - window.clearTimeout(this.timeoutId); - } - } -} diff --git a/x-pack/plugins/apm/public/components/shared/useDelayedVisibility/index.test.tsx b/x-pack/plugins/apm/public/components/shared/useDelayedVisibility/index.test.tsx deleted file mode 100644 index 447e11eab5e41..0000000000000 --- a/x-pack/plugins/apm/public/components/shared/useDelayedVisibility/index.test.tsx +++ /dev/null @@ -1,86 +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 { - renderHook, - act, - RenderHookResult, -} from '@testing-library/react-hooks'; -import { useDelayedVisibility } from '.'; - -// Failing: See https://github.com/elastic/kibana/issues/66389 -describe.skip('useFetcher', () => { - let hook: RenderHookResult; - - beforeEach(() => { - jest.useFakeTimers(); - }); - - it('is initially false', () => { - hook = renderHook((isLoading) => useDelayedVisibility(isLoading), { - initialProps: false, - }); - expect(hook.result.current).toEqual(false); - }); - - it('does not change to true immediately', () => { - hook = renderHook((isLoading) => useDelayedVisibility(isLoading), { - initialProps: false, - }); - - hook.rerender(true); - act(() => { - jest.advanceTimersByTime(10); - }); - - expect(hook.result.current).toEqual(false); - act(() => { - jest.advanceTimersByTime(50); - }); - - expect(hook.result.current).toEqual(true); - }); - - it('does not change to false immediately', () => { - hook = renderHook((isLoading) => useDelayedVisibility(isLoading), { - initialProps: false, - }); - - hook.rerender(true); - act(() => { - jest.advanceTimersByTime(100); - }); - hook.rerender(false); - - expect(hook.result.current).toEqual(true); - }); - - // Disabled because it's flaky: https://github.com/elastic/kibana/issues/66389 - // it('is true for minimum 1000ms', () => { - // hook = renderHook((isLoading) => useDelayedVisibility(isLoading), { - // initialProps: false, - // }); - - // hook.rerender(true); - - // act(() => { - // jest.advanceTimersByTime(100); - // }); - - // hook.rerender(false); - // act(() => { - // jest.advanceTimersByTime(900); - // }); - - // expect(hook.result.current).toEqual(true); - - // act(() => { - // jest.advanceTimersByTime(100); - // }); - - // expect(hook.result.current).toEqual(false); - // }); -}); diff --git a/x-pack/plugins/apm/public/components/shared/useDelayedVisibility/index.ts b/x-pack/plugins/apm/public/components/shared/useDelayedVisibility/index.ts deleted file mode 100644 index bd5708494d641..0000000000000 --- a/x-pack/plugins/apm/public/components/shared/useDelayedVisibility/index.ts +++ /dev/null @@ -1,48 +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 { useEffect, useRef, useState } from 'react'; -import { Delayed } from './Delayed'; - -export function useDelayedVisibility( - visible: boolean, - hideDelayMs?: number, - showDelayMs?: number, - minimumVisibleDuration?: number -) { - const [isVisible, setIsVisible] = useState(false); - const delayedRef = useRef(null); - - useEffect(() => { - const delayed = new Delayed({ - hideDelayMs, - showDelayMs, - minimumVisibleDuration, - }); - delayed.onChange((visibility) => { - setIsVisible(visibility); - }); - delayedRef.current = delayed; - - return () => { - delayed.destroy(); - }; - }, [hideDelayMs, showDelayMs, minimumVisibleDuration]); - - useEffect(() => { - if (!delayedRef.current) { - return; - } - - if (visible) { - delayedRef.current.show(); - } else { - delayedRef.current.hide(); - } - }, [visible]); - - return isVisible; -} diff --git a/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx b/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx deleted file mode 100644 index 99822c0bbc5ca..0000000000000 --- a/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx +++ /dev/null @@ -1,65 +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 { EuiPortal, EuiProgress } from '@elastic/eui'; -import { pickBy } from 'lodash'; -import React, { Fragment, useMemo, useReducer } from 'react'; -import { useDelayedVisibility } from '../components/shared/useDelayedVisibility'; - -export const LoadingIndicatorContext = React.createContext({ - statuses: {}, - dispatchStatus: (_action: Action) => {}, -}); - -interface State { - [key: string]: boolean; -} - -interface Action { - isLoading: boolean; - id: number; -} - -function reducer(statuses: State, action: Action) { - // Return an object with only the ids with `true` as their value, so that ids - // that previously had `false` are removed and do not remain hanging around in - // the object. - return pickBy( - { ...statuses, [action.id.toString()]: action.isLoading }, - Boolean - ); -} - -function getIsAnyLoading(statuses: State) { - return Object.values(statuses).some((isLoading) => isLoading); -} - -export function LoadingIndicatorProvider({ - children, -}: { - children: React.ReactNode; -}) { - const [statuses, dispatchStatus] = useReducer(reducer, {}); - const isLoading = useMemo(() => getIsAnyLoading(statuses), [statuses]); - const shouldShowLoadingIndicator = useDelayedVisibility(isLoading); - const contextValue = React.useMemo(() => ({ statuses, dispatchStatus }), [ - statuses, - ]); - - return ( - - {shouldShowLoadingIndicator && ( - - - - )} - - - - ); -} diff --git a/x-pack/plugins/apm/public/context/UrlParamsContext/index.tsx b/x-pack/plugins/apm/public/context/UrlParamsContext/index.tsx index 9eb4704a2ca29..5682009019d7f 100644 --- a/x-pack/plugins/apm/public/context/UrlParamsContext/index.tsx +++ b/x-pack/plugins/apm/public/context/UrlParamsContext/index.tsx @@ -25,6 +25,7 @@ import { import { pickKeys } from '../../../common/utils/pick_keys'; import { useDeepObjectIdentity } from '../../hooks/useDeepObjectIdentity'; import { LocalUIFilterName } from '../../../common/ui_filter'; +import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values'; interface TimeRange { rangeFrom: string; @@ -38,7 +39,11 @@ function useUiFilters(params: IUrlParams): UIFilters { (val) => (val ? val.split(',') : []) ) as Partial>; - return useDeepObjectIdentity({ kuery, environment, ...localUiFilters }); + return useDeepObjectIdentity({ + kuery, + environment: environment || ENVIRONMENT_ALL.value, + ...localUiFilters, + }); } const defaultRefresh = (_time: TimeRange) => {}; diff --git a/x-pack/plugins/apm/public/hooks/useFetcher.tsx b/x-pack/plugins/apm/public/hooks/useFetcher.tsx index 68b197c46e888..5d65424844c5a 100644 --- a/x-pack/plugins/apm/public/hooks/useFetcher.tsx +++ b/x-pack/plugins/apm/public/hooks/useFetcher.tsx @@ -4,14 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext, useEffect, useState, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; +import React, { useEffect, useMemo, useState } from 'react'; import { IHttpFetchError } from 'src/core/public'; import { toMountPoint } from '../../../../../src/plugins/kibana_react/public'; -import { LoadingIndicatorContext } from '../context/LoadingIndicatorContext'; import { APMClient, callApmApi } from '../services/rest/createCallApmApi'; import { useApmPluginContext } from './useApmPluginContext'; -import { useLoadingIndicator } from './useLoadingIndicator'; export enum FETCH_STATUS { LOADING = 'loading', @@ -44,9 +42,6 @@ export function useFetcher( ): FetcherResult> & { refetch: () => void } { const { notifications } = useApmPluginContext().core; const { preservePreviousData = true, showToastOnError = true } = options; - const { setIsLoading } = useLoadingIndicator(); - - const { dispatchStatus } = useContext(LoadingIndicatorContext); const [result, setResult] = useState< FetcherResult> >({ @@ -67,8 +62,6 @@ export function useFetcher( return; } - setIsLoading(true); - setResult((prevResult) => ({ data: preservePreviousData ? prevResult.data : undefined, // preserve data from previous state while loading next state status: FETCH_STATUS.LOADING, @@ -78,7 +71,6 @@ export function useFetcher( try { const data = await promise; if (!didCancel) { - setIsLoading(false); setResult({ data, status: FETCH_STATUS.SUCCESS, @@ -122,7 +114,6 @@ export function useFetcher( ), }); } - setIsLoading(false); setResult({ data: undefined, status: FETCH_STATUS.FAILURE, @@ -135,7 +126,6 @@ export function useFetcher( doFetch(); return () => { - setIsLoading(false); didCancel = true; }; /* eslint-disable react-hooks/exhaustive-deps */ @@ -143,8 +133,6 @@ export function useFetcher( counter, preservePreviousData, showToastOnError, - dispatchStatus, - setIsLoading, ...fnDeps, /* eslint-enable react-hooks/exhaustive-deps */ ]); diff --git a/x-pack/plugins/apm/public/hooks/useLoadingIndicator.ts b/x-pack/plugins/apm/public/hooks/useLoadingIndicator.ts deleted file mode 100644 index 6742efb0ffbae..0000000000000 --- a/x-pack/plugins/apm/public/hooks/useLoadingIndicator.ts +++ /dev/null @@ -1,28 +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 { useContext, useMemo, useEffect } from 'react'; -import { LoadingIndicatorContext } from '../context/LoadingIndicatorContext'; -import { useComponentId } from './useComponentId'; - -export function useLoadingIndicator() { - const { dispatchStatus } = useContext(LoadingIndicatorContext); - const id = useComponentId(); - - useEffect(() => { - return () => { - dispatchStatus({ id, isLoading: false }); - }; - }, [dispatchStatus, id]); - - return useMemo(() => { - return { - setIsLoading: (loading: boolean) => { - dispatchStatus({ id, isLoading: loading }); - }, - }; - }, [dispatchStatus, id]); -} diff --git a/x-pack/plugins/apm/public/hooks/useTransactionDistribution.ts b/x-pack/plugins/apm/public/hooks/useTransactionDistribution.ts index cd3e02d155602..a5096a314388c 100644 --- a/x-pack/plugins/apm/public/hooks/useTransactionDistribution.ts +++ b/x-pack/plugins/apm/public/hooks/useTransactionDistribution.ts @@ -75,7 +75,7 @@ export function useTransactionDistribution(urlParams: IUrlParams) { const preferredSample = maybe(bucketsSortedByCount[0]?.samples[0]); - history.push({ + history.replace({ ...history.location, search: fromQuery({ ...omit(toQuery(history.location.search), [ diff --git a/x-pack/plugins/apm/public/utils/testHelpers.tsx b/x-pack/plugins/apm/public/utils/testHelpers.tsx index 971455fde3946..7826e9672a3bb 100644 --- a/x-pack/plugins/apm/public/utils/testHelpers.tsx +++ b/x-pack/plugins/apm/public/utils/testHelpers.tsx @@ -25,6 +25,7 @@ import { } from '../../typings/elasticsearch'; import { MockApmPluginContextWrapper } from '../context/ApmPluginContext/MockApmPluginContext'; import { UrlParamsProvider } from '../context/UrlParamsContext'; +import { UIFilters } from '../../typings/ui_filters'; const originalConsoleWarn = console.warn; // eslint-disable-line no-console /** @@ -118,7 +119,8 @@ interface MockSetup { apmEventClient: any; internalClient: any; config: APMConfig; - uiFiltersES: ESFilter[]; + uiFilters: UIFilters; + esFilter: ESFilter[]; indices: { /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': string; @@ -179,7 +181,8 @@ export async function inspectSearchParams( }, } ) as APMConfig, - uiFiltersES: [{ term: { 'my.custom.ui.filter': 'foo-bar' } }], + uiFilters: { environment: 'test' }, + esFilter: [{ term: { 'service.environment': 'test' } }], indices: { /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': 'myIndex', diff --git a/x-pack/plugins/apm/scripts/aggregate-latency-metrics.js b/x-pack/plugins/apm/scripts/aggregate-latency-metrics.js index 287f267343b11..15414c8166520 100644 --- a/x-pack/plugins/apm/scripts/aggregate-latency-metrics.js +++ b/x-pack/plugins/apm/scripts/aggregate-latency-metrics.js @@ -4,17 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ // eslint-disable-next-line import/no-extraneous-dependencies -require('@babel/register')({ - extensions: ['.ts'], - plugins: [ - '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-proposal-nullish-coalescing-operator', - ], - presets: [ - '@babel/typescript', - ['@babel/preset-env', { targets: { node: 'current' } }], - ], -}); +require('@kbn/optimizer').registerNodeAutoTranspilation(); const { aggregateLatencyMetrics, diff --git a/x-pack/plugins/apm/scripts/create-functional-tests-archive.js b/x-pack/plugins/apm/scripts/create-functional-tests-archive.js index 6b3473dc2ac0a..ce265acf39c8b 100644 --- a/x-pack/plugins/apm/scripts/create-functional-tests-archive.js +++ b/x-pack/plugins/apm/scripts/create-functional-tests-archive.js @@ -6,13 +6,6 @@ // compile typescript on the fly // eslint-disable-next-line import/no-extraneous-dependencies -require('@babel/register')({ - extensions: ['.js', '.ts'], - plugins: ['@babel/plugin-proposal-optional-chaining'], - presets: [ - '@babel/typescript', - ['@babel/preset-env', { targets: { node: 'current' } }], - ], -}); +require('@kbn/optimizer').registerNodeAutoTranspilation(); require('./create-functional-tests-archive/index.ts'); diff --git a/x-pack/plugins/apm/scripts/jest.js b/x-pack/plugins/apm/scripts/jest.js index 5c29dd9126937..3a73dbf6e3464 100644 --- a/x-pack/plugins/apm/scripts/jest.js +++ b/x-pack/plugins/apm/scripts/jest.js @@ -4,14 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ // eslint-disable-next-line import/no-extraneous-dependencies -require('@babel/register')({ - extensions: ['.js'], - plugins: [], - presets: [ - '@babel/typescript', - ['@babel/preset-env', { targets: { node: 'current' } }], - ], -}); +require('@kbn/optimizer').registerNodeAutoTranspilation(); // eslint-disable-next-line import/no-extraneous-dependencies const { run } = require('jest'); diff --git a/x-pack/plugins/apm/scripts/package.json b/x-pack/plugins/apm/scripts/package.json index d3e2d42f972a9..c68dc49cd9370 100644 --- a/x-pack/plugins/apm/scripts/package.json +++ b/x-pack/plugins/apm/scripts/package.json @@ -4,7 +4,7 @@ "main": "index.js", "license": "MIT", "dependencies": { - "@elastic/elasticsearch": "7.9.0-rc.1", + "@elastic/elasticsearch": "7.9.1", "@octokit/rest": "^16.35.0", "console-stamp": "^0.2.9", "hdr-histogram-js": "^1.2.0" diff --git a/x-pack/plugins/apm/scripts/setup-kibana-security.js b/x-pack/plugins/apm/scripts/setup-kibana-security.js index 414d7208a7864..86b8c30988ca5 100644 --- a/x-pack/plugins/apm/scripts/setup-kibana-security.js +++ b/x-pack/plugins/apm/scripts/setup-kibana-security.js @@ -17,13 +17,6 @@ // compile typescript on the fly // eslint-disable-next-line import/no-extraneous-dependencies -require('@babel/register')({ - extensions: ['.ts'], - plugins: ['@babel/plugin-proposal-optional-chaining'], - presets: [ - '@babel/typescript', - ['@babel/preset-env', { targets: { node: 'current' } }], - ], -}); +require('@kbn/optimizer').registerNodeAutoTranspilation(); require('./kibana-security/setup-custom-kibana-user-role.ts'); diff --git a/x-pack/plugins/apm/scripts/upload-telemetry-data.js b/x-pack/plugins/apm/scripts/upload-telemetry-data.js index 03cd5095ec02d..76bf9c5aebe64 100644 --- a/x-pack/plugins/apm/scripts/upload-telemetry-data.js +++ b/x-pack/plugins/apm/scripts/upload-telemetry-data.js @@ -6,16 +6,6 @@ // compile typescript on the fly // eslint-disable-next-line import/no-extraneous-dependencies -require('@babel/register')({ - extensions: ['.ts'], - plugins: [ - '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-proposal-nullish-coalescing-operator', - ], - presets: [ - '@babel/typescript', - ['@babel/preset-env', { targets: { node: 'current' } }], - ], -}); +require('@kbn/optimizer').registerNodeAutoTranspilation(); require('./upload-telemetry-data/index.ts'); diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts index f78280aa7428e..c93fdfc15fe3c 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts @@ -6,7 +6,6 @@ import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { DeepRequired } from 'utility-types'; import { CoreSetup, Logger, @@ -21,14 +20,14 @@ import { APM_TELEMETRY_SAVED_OBJECT_ID, APM_TELEMETRY_SAVED_OBJECT_TYPE, } from '../../../common/apm_saved_object_constants'; -import { getApmTelemetryMapping } from '../../../common/apm_telemetry'; import { getInternalSavedObjectsClient } from '../helpers/get_internal_saved_objects_client'; import { getApmIndices } from '../settings/apm_indices/get_apm_indices'; import { collectDataTelemetry, CollectTelemetryParams, } from './collect_data_telemetry'; -import { APMDataTelemetry } from './types'; +import { APMUsage } from './types'; +import { apmSchema } from './schema'; const APM_TELEMETRY_TASK_NAME = 'apm-telemetry-task'; @@ -107,9 +106,9 @@ export async function createApmTelemetry({ ); }; - const collector = usageCollector.makeUsageCollector({ + const collector = usageCollector.makeUsageCollector({ type: 'apm', - schema: getApmTelemetryMapping(), + schema: apmSchema, fetch: async () => { try { const { kibanaVersion: storedKibanaVersion, ...data } = ( @@ -117,9 +116,7 @@ export async function createApmTelemetry({ APM_TELEMETRY_SAVED_OBJECT_TYPE, APM_TELEMETRY_SAVED_OBJECT_ID ) - ).attributes as { kibanaVersion: string } & DeepRequired< - APMDataTelemetry - >; + ).attributes as { kibanaVersion: string } & APMUsage; return data; } catch (err) { diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/schema.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/schema.ts new file mode 100644 index 0000000000000..4bbda9add0fdb --- /dev/null +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/schema.ts @@ -0,0 +1,206 @@ +/* + * 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 { MakeSchemaFrom } from 'src/plugins/usage_collection/server'; +import { + AggregatedTransactionsCounts, + APMUsage, + TimeframeMap, + TimeframeMap1d, + TimeframeMapAll, +} from './types'; +import { AgentName } from '../../../typings/es_schemas/ui/fields/agent'; + +const long: { type: 'long' } = { type: 'long' }; + +const aggregatedTransactionCountSchema: MakeSchemaFrom = { + expected_metric_document_count: long, + transaction_count: long, +}; + +const timeframeMap1dSchema: MakeSchemaFrom = { + '1d': long, +}; + +const timeframeMapAllSchema: MakeSchemaFrom = { + all: long, +}; + +const timeframeMapSchema: MakeSchemaFrom = { + ...timeframeMap1dSchema, + ...timeframeMapAllSchema, +}; + +const agentSchema: MakeSchemaFrom['agents'][AgentName] = { + agent: { + version: { type: 'array', items: { type: 'keyword' } }, + }, + service: { + framework: { + name: { type: 'array', items: { type: 'keyword' } }, + version: { type: 'array', items: { type: 'keyword' } }, + composite: { type: 'array', items: { type: 'keyword' } }, + }, + language: { + name: { type: 'array', items: { type: 'keyword' } }, + version: { type: 'array', items: { type: 'keyword' } }, + composite: { type: 'array', items: { type: 'keyword' } }, + }, + runtime: { + name: { type: 'array', items: { type: 'keyword' } }, + version: { type: 'array', items: { type: 'keyword' } }, + composite: { type: 'array', items: { type: 'keyword' } }, + }, + }, +}; + +const apmPerAgentSchema: Pick< + MakeSchemaFrom, + 'services_per_agent' | 'agents' +> = { + // services_per_agent: AGENT_NAMES.reduce( + // (acc, name) => ({ ...acc, [name]: long }), + // {} as Record + // ), + // agents: AGENT_NAMES.reduce( + // (acc, name) => ({ ...acc, [name]: agentSchema }), + // {} as Record + // ), + // TODO: Find a way for `@kbn/telemetry-tools` to understand and evaluate expressions. + // In the meanwhile, we'll have to maintain these lists up to date (TS will remind us to update) + services_per_agent: { + dotnet: long, + go: long, + java: long, + 'js-base': long, + nodejs: long, + python: long, + ruby: long, + 'rum-js': long, + otlp: long, + 'opentelemetry/cpp': long, + 'opentelemetry/dotnet': long, + 'opentelemetry/erlang': long, + 'opentelemetry/go': long, + 'opentelemetry/java': long, + 'opentelemetry/nodejs': long, + 'opentelemetry/php': long, + 'opentelemetry/python': long, + 'opentelemetry/ruby': long, + 'opentelemetry/webjs': long, + }, + agents: { + dotnet: agentSchema, + go: agentSchema, + java: agentSchema, + 'js-base': agentSchema, + nodejs: agentSchema, + python: agentSchema, + ruby: agentSchema, + 'rum-js': agentSchema, + otlp: agentSchema, + 'opentelemetry/cpp': agentSchema, + 'opentelemetry/dotnet': agentSchema, + 'opentelemetry/erlang': agentSchema, + 'opentelemetry/go': agentSchema, + 'opentelemetry/java': agentSchema, + 'opentelemetry/nodejs': agentSchema, + 'opentelemetry/php': agentSchema, + 'opentelemetry/python': agentSchema, + 'opentelemetry/ruby': agentSchema, + 'opentelemetry/webjs': agentSchema, + }, +}; + +export const apmSchema: MakeSchemaFrom = { + ...apmPerAgentSchema, + has_any_services: { type: 'boolean' }, + version: { + apm_server: { + major: long, + minor: long, + patch: long, + }, + }, + environments: { + services_without_environments: long, + services_with_multiple_environments: long, + top_environments: { type: 'array', items: { type: 'keyword' } }, + }, + aggregated_transactions: { + current_implementation: aggregatedTransactionCountSchema, + no_observer_name: aggregatedTransactionCountSchema, + no_rum: aggregatedTransactionCountSchema, + no_rum_no_observer_name: aggregatedTransactionCountSchema, + only_rum: aggregatedTransactionCountSchema, + only_rum_no_observer_name: aggregatedTransactionCountSchema, + }, + cloud: { + availability_zone: { type: 'array', items: { type: 'keyword' } }, + provider: { type: 'array', items: { type: 'keyword' } }, + region: { type: 'array', items: { type: 'keyword' } }, + }, + counts: { + transaction: timeframeMapSchema, + span: timeframeMapSchema, + error: timeframeMapSchema, + metric: timeframeMapSchema, + sourcemap: timeframeMapSchema, + onboarding: timeframeMapSchema, + agent_configuration: timeframeMapAllSchema, + max_transaction_groups_per_service: timeframeMapSchema, + max_error_groups_per_service: timeframeMapSchema, + traces: timeframeMapSchema, + services: timeframeMapSchema, + }, + cardinality: { + client: { geo: { country_iso_code: { rum: timeframeMap1dSchema } } }, + user_agent: { + original: { + all_agents: timeframeMap1dSchema, + rum: timeframeMap1dSchema, + }, + }, + transaction: { + name: { + all_agents: timeframeMap1dSchema, + rum: timeframeMap1dSchema, + }, + }, + }, + retainment: { + span: { ms: long }, + transaction: { ms: long }, + error: { ms: long }, + metric: { ms: long }, + sourcemap: { ms: long }, + onboarding: { ms: long }, + }, + integrations: { ml: { all_jobs_count: long } }, + + indices: { + shards: { total: long }, + all: { + total: { + docs: { count: long }, + store: { size_in_bytes: long }, + }, + }, + }, + tasks: { + aggregated_transactions: { took: { ms: long } }, + cloud: { took: { ms: long } }, + processor_events: { took: { ms: long } }, + agent_configuration: { took: { ms: long } }, + services: { took: { ms: long } }, + versions: { took: { ms: long } }, + groupings: { took: { ms: long } }, + integrations: { took: { ms: long } }, + agents: { took: { ms: long } }, + indices_stats: { took: { ms: long } }, + cardinality: { took: { ms: long } }, + }, +}; diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/types.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/types.ts index c7af292e817c7..7ed79752b43c4 100644 --- a/x-pack/plugins/apm/server/lib/apm_telemetry/types.ts +++ b/x-pack/plugins/apm/server/lib/apm_telemetry/types.ts @@ -20,7 +20,7 @@ export interface AggregatedTransactionsCounts { transaction_count: number; } -export type APMDataTelemetry = DeepPartial<{ +export interface APMUsage { has_any_services: boolean; services_per_agent: Record; version: { @@ -139,6 +139,8 @@ export type APMDataTelemetry = DeepPartial<{ | 'cardinality', { took: { ms: number } } >; -}>; +} + +export type APMDataTelemetry = DeepPartial; export type APMTelemetry = APMDataTelemetry; diff --git a/x-pack/plugins/apm/server/lib/errors/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/errors/__snapshots__/queries.test.ts.snap index 63b6c9cde4d0d..632232ffb075d 100644 --- a/x-pack/plugins/apm/server/lib/errors/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/errors/__snapshots__/queries.test.ts.snap @@ -32,7 +32,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -119,7 +119,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -194,7 +194,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], diff --git a/x-pack/plugins/apm/server/lib/errors/distribution/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/errors/distribution/__snapshots__/queries.test.ts.snap index ea142ca2acc00..b329499c8b045 100644 --- a/x-pack/plugins/apm/server/lib/errors/distribution/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/errors/distribution/__snapshots__/queries.test.ts.snap @@ -40,7 +40,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -91,7 +91,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { diff --git a/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts b/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts index 1a83113de35f2..50da1f9c20d16 100644 --- a/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts +++ b/x-pack/plugins/apm/server/lib/errors/distribution/__tests__/get_buckets.test.ts @@ -41,7 +41,10 @@ describe('timeseriesFetcher', () => { get: () => 'myIndex', } ) as APMConfig, - uiFiltersES: [ + uiFilters: { + environment: 'prod', + }, + esFilter: [ { term: { 'service.environment': 'prod' }, }, diff --git a/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts b/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts index de6df15354e79..a42710947a792 100644 --- a/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts +++ b/x-pack/plugins/apm/server/lib/errors/distribution/get_buckets.ts @@ -11,11 +11,7 @@ import { SERVICE_NAME, } from '../../../../common/elasticsearch_fieldnames'; import { rangeFilter } from '../../../../common/utils/range_filter'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; export async function getBuckets({ serviceName, @@ -26,13 +22,13 @@ export async function getBuckets({ serviceName: string; groupId?: string; bucketSize: number; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; }) { - const { start, end, uiFiltersES, apmEventClient } = setup; + const { start, end, esFilter, apmEventClient } = setup; const filter: ESFilter[] = [ { term: { [SERVICE_NAME]: serviceName } }, { range: rangeFilter(start, end) }, - ...uiFiltersES, + ...esFilter, ]; if (groupId) { diff --git a/x-pack/plugins/apm/server/lib/errors/distribution/get_distribution.ts b/x-pack/plugins/apm/server/lib/errors/distribution/get_distribution.ts index 3b48b6c5be594..dea518cad8e40 100644 --- a/x-pack/plugins/apm/server/lib/errors/distribution/get_distribution.ts +++ b/x-pack/plugins/apm/server/lib/errors/distribution/get_distribution.ts @@ -5,11 +5,7 @@ */ import { PromiseReturnType } from '../../../../typings/common'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; import { getBuckets } from './get_buckets'; import { BUCKET_TARGET_COUNT } from '../../transactions/constants'; @@ -28,7 +24,7 @@ export async function getErrorDistribution({ }: { serviceName: string; groupId?: string; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; }) { const bucketSize = getBucketSize({ start: setup.start, end: setup.end }); const { buckets, noHits } = await getBuckets({ diff --git a/x-pack/plugins/apm/server/lib/errors/get_error_group.ts b/x-pack/plugins/apm/server/lib/errors/get_error_group.ts index b23c955b57183..0fbc7720f7111 100644 --- a/x-pack/plugins/apm/server/lib/errors/get_error_group.ts +++ b/x-pack/plugins/apm/server/lib/errors/get_error_group.ts @@ -12,11 +12,7 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { PromiseReturnType } from '../../../typings/common'; import { rangeFilter } from '../../../common/utils/range_filter'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getTransaction } from '../transactions/get_transaction'; export type ErrorGroupAPIResponse = PromiseReturnType; @@ -29,9 +25,9 @@ export async function getErrorGroup({ }: { serviceName: string; groupId: string; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; }) { - const { start, end, uiFiltersES, apmEventClient } = setup; + const { start, end, esFilter, apmEventClient } = setup; const params = { apm: { @@ -45,7 +41,7 @@ export async function getErrorGroup({ { term: { [SERVICE_NAME]: serviceName } }, { term: { [ERROR_GROUP_ID]: groupId } }, { range: rangeFilter(start, end) }, - ...uiFiltersES, + ...esFilter, ], should: [{ term: { [TRANSACTION_SAMPLED]: true } }], }, diff --git a/x-pack/plugins/apm/server/lib/errors/get_error_groups.ts b/x-pack/plugins/apm/server/lib/errors/get_error_groups.ts index ab1c2149be343..006d2fae3d4fb 100644 --- a/x-pack/plugins/apm/server/lib/errors/get_error_groups.ts +++ b/x-pack/plugins/apm/server/lib/errors/get_error_groups.ts @@ -13,11 +13,7 @@ import { ERROR_LOG_MESSAGE, } from '../../../common/elasticsearch_fieldnames'; import { PromiseReturnType } from '../../../typings/common'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getErrorGroupsProjection } from '../../projections/errors'; import { mergeProjection } from '../../projections/util/merge_projection'; import { SortOptions } from '../../../typings/elasticsearch/aggregations'; @@ -35,7 +31,7 @@ export async function getErrorGroups({ serviceName: string; sortField?: string; sortDirection?: 'asc' | 'desc'; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; }) { const { apmEventClient } = setup; diff --git a/x-pack/plugins/apm/server/lib/helpers/convert_ui_filters/get_ui_filters_es.ts b/x-pack/plugins/apm/server/lib/helpers/convert_ui_filters/get_es_filter.ts similarity index 96% rename from x-pack/plugins/apm/server/lib/helpers/convert_ui_filters/get_ui_filters_es.ts rename to x-pack/plugins/apm/server/lib/helpers/convert_ui_filters/get_es_filter.ts index c1405b44f2a8a..1b8f32d4de8b9 100644 --- a/x-pack/plugins/apm/server/lib/helpers/convert_ui_filters/get_ui_filters_es.ts +++ b/x-pack/plugins/apm/server/lib/helpers/convert_ui_filters/get_es_filter.ts @@ -13,7 +13,7 @@ import { } from '../../ui_filters/local_ui_filters/config'; import { esKuery } from '../../../../../../../src/plugins/data/server'; -export function getUiFiltersES(uiFilters: UIFilters) { +export function getEsFilter(uiFilters: UIFilters) { const { kuery, environment, ...localFilterValues } = uiFilters; const mappedFilters = localUIFilterNames .filter((name) => name in localFilterValues) diff --git a/x-pack/plugins/apm/server/lib/helpers/convert_ui_filters/get_parsed_ui_filters.ts b/x-pack/plugins/apm/server/lib/helpers/convert_ui_filters/get_parsed_ui_filters.ts deleted file mode 100644 index 324da199807c7..0000000000000 --- a/x-pack/plugins/apm/server/lib/helpers/convert_ui_filters/get_parsed_ui_filters.ts +++ /dev/null @@ -1,23 +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 { Logger } from 'src/core/server'; -import { UIFilters } from '../../../../typings/ui_filters'; - -export function getParsedUiFilters({ - uiFilters, - logger, -}: { - uiFilters: string; - logger: Logger; -}): UIFilters { - try { - return JSON.parse(uiFilters); - } catch (error) { - logger.error(error); - } - return {}; -} diff --git a/x-pack/plugins/apm/server/lib/helpers/setup_request.ts b/x-pack/plugins/apm/server/lib/helpers/setup_request.ts index eba75433a5148..26896a050dd88 100644 --- a/x-pack/plugins/apm/server/lib/helpers/setup_request.ts +++ b/x-pack/plugins/apm/server/lib/helpers/setup_request.ts @@ -5,6 +5,7 @@ */ import moment from 'moment'; +import { Logger } from 'kibana/server'; import { isActivePlatinumLicense } from '../../../common/service_map'; import { UI_SETTINGS } from '../../../../../../src/plugins/data/common'; import { KibanaRequest } from '../../../../../../src/core/server'; @@ -14,7 +15,7 @@ import { ApmIndicesConfig, } from '../settings/apm_indices/get_apm_indices'; import { ESFilter } from '../../../typings/elasticsearch'; -import { getUiFiltersES } from './convert_ui_filters/get_ui_filters_es'; +import { getEsFilter } from './convert_ui_filters/get_es_filter'; import { APMRequestHandlerContext } from '../../routes/typings'; import { ProcessorEvent } from '../../../common/processor_event'; import { @@ -25,14 +26,8 @@ import { APMInternalClient, createInternalESClient, } from './create_es_client/create_internal_es_client'; +import { UIFilters } from '../../../typings/ui_filters'; -function decodeUiFilters(uiFiltersEncoded?: string) { - if (!uiFiltersEncoded) { - return []; - } - const uiFilters = JSON.parse(uiFiltersEncoded); - return getUiFiltersES(uiFilters); -} // Explicitly type Setup to prevent TS initialization errors // https://github.com/microsoft/TypeScript/issues/34933 @@ -42,6 +37,8 @@ export interface Setup { ml?: ReturnType; config: APMConfig; indices: ApmIndicesConfig; + uiFilters: UIFilters; + esFilter: ESFilter[]; } export interface SetupTimeRange { @@ -49,10 +46,6 @@ export interface SetupTimeRange { end: number; } -export interface SetupUIFilters { - uiFiltersES: ESFilter[]; -} - interface SetupRequestParams { query?: { _debug?: boolean; @@ -65,16 +58,13 @@ interface SetupRequestParams { type InferSetup = Setup & (TParams extends { query: { start: string } } ? { start: number } : {}) & - (TParams extends { query: { end: string } } ? { end: number } : {}) & - (TParams extends { query: { uiFilters: string } } - ? { uiFiltersES: ESFilter[] } - : {}); + (TParams extends { query: { end: string } } ? { end: number } : {}); export async function setupRequest( context: APMRequestHandlerContext, request: KibanaRequest ): Promise> { - const { config } = context; + const { config, logger } = context; const { query } = context.params; const [indices, includeFrozen] = await Promise.all([ @@ -85,7 +75,7 @@ export async function setupRequest( context.core.uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN), ]); - const uiFiltersES = decodeUiFilters(query.uiFilters); + const uiFilters = decodeUiFilters(logger, query.uiFilters); const coreSetupRequest = { indices, @@ -108,12 +98,13 @@ export async function setupRequest( ) : undefined, config, + uiFilters, + esFilter: getEsFilter(uiFilters), }; return { ...('start' in query ? { start: moment.utc(query.start).valueOf() } : {}), ...('end' in query ? { end: moment.utc(query.end).valueOf() } : {}), - ...('uiFilters' in query ? { uiFiltersES } : {}), ...coreSetupRequest, } as InferSetup; } @@ -129,3 +120,15 @@ function getMlSetup( modules: ml.modulesProvider(request, savedObjectsClient), }; } + +function decodeUiFilters(logger: Logger, uiFiltersEncoded?: string): UIFilters { + if (!uiFiltersEncoded) { + return {}; + } + try { + return JSON.parse(uiFiltersEncoded); + } catch (error) { + logger.error(error); + return {}; + } +} diff --git a/x-pack/plugins/apm/server/lib/metrics/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/metrics/__snapshots__/queries.test.ts.snap index 2868dcfda97b6..961a1eee61d1d 100644 --- a/x-pack/plugins/apm/server/lib/metrics/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/metrics/__snapshots__/queries.test.ts.snap @@ -87,7 +87,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -175,7 +175,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -206,7 +206,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -231,7 +231,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -258,7 +258,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -283,7 +283,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -338,7 +338,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -431,7 +431,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -514,7 +514,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -623,7 +623,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -717,7 +717,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -748,7 +748,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -773,7 +773,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -800,7 +800,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -825,7 +825,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -886,7 +886,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -985,7 +985,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -1074,7 +1074,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -1172,7 +1172,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -1255,7 +1255,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -1286,7 +1286,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -1311,7 +1311,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -1338,7 +1338,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -1363,7 +1363,7 @@ Object { "lang": "painless", "source": " /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -1413,7 +1413,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -1501,7 +1501,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -1579,7 +1579,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/default.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/default.ts index 6ee507d7b9bb1..fbcbc9f12791f 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/default.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/default.ts @@ -4,16 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; import { getCPUChartData } from './shared/cpu'; import { getMemoryChartData } from './shared/memory'; export async function getDefaultMetricsCharts( - setup: Setup & SetupTimeRange & SetupUIFilters, + setup: Setup & SetupTimeRange, serviceName: string ) { const charts = await Promise.all([ diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts index d7e64bdcacd12..2ed11480a7585 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/fetch_and_transform_gc_metrics.ts @@ -11,11 +11,7 @@ import { sum, round } from 'lodash'; import theme from '@elastic/eui/dist/eui_theme_light.json'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../../helpers/setup_request'; import { getMetricsDateHistogramParams } from '../../../../helpers/metrics'; import { ChartBase } from '../../../types'; import { getMetricsProjection } from '../../../../../projections/metrics'; @@ -36,7 +32,7 @@ export async function fetchAndTransformGcMetrics({ chartBase, fieldName, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; serviceName: string; serviceNodeName?: string; chartBase: ChartBase; diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/get_gc_rate_chart.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/get_gc_rate_chart.ts index 6e562b9a8ee87..7cedeb828e3b7 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/get_gc_rate_chart.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/get_gc_rate_chart.ts @@ -7,11 +7,7 @@ import theme from '@elastic/eui/dist/eui_theme_light.json'; import { i18n } from '@kbn/i18n'; import { METRIC_JAVA_GC_COUNT } from '../../../../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../../helpers/setup_request'; import { fetchAndTransformGcMetrics } from './fetch_and_transform_gc_metrics'; import { ChartBase } from '../../../types'; @@ -35,7 +31,7 @@ const chartBase: ChartBase = { }; const getGcRateChart = ( - setup: Setup & SetupTimeRange & SetupUIFilters, + setup: Setup & SetupTimeRange, serviceName: string, serviceNodeName?: string ) => { diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/get_gc_time_chart.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/get_gc_time_chart.ts index 0b9d6240fc1c9..f21d3d8e7c056 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/get_gc_time_chart.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/gc/get_gc_time_chart.ts @@ -7,11 +7,7 @@ import theme from '@elastic/eui/dist/eui_theme_light.json'; import { i18n } from '@kbn/i18n'; import { METRIC_JAVA_GC_TIME } from '../../../../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../../helpers/setup_request'; import { fetchAndTransformGcMetrics } from './fetch_and_transform_gc_metrics'; import { ChartBase } from '../../../types'; @@ -35,7 +31,7 @@ const chartBase: ChartBase = { }; const getGcTimeChart = ( - setup: Setup & SetupTimeRange & SetupUIFilters, + setup: Setup & SetupTimeRange, serviceName: string, serviceNodeName?: string ) => { diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/heap_memory/index.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/heap_memory/index.ts index ba3183c0fa7d7..eb79897f9f055 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/heap_memory/index.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/heap_memory/index.ts @@ -12,11 +12,7 @@ import { METRIC_JAVA_HEAP_MEMORY_USED, AGENT_NAME, } from '../../../../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../../helpers/setup_request'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; import { ChartBase } from '../../../types'; @@ -55,7 +51,7 @@ const chartBase: ChartBase = { }; export async function getHeapMemoryChart( - setup: Setup & SetupTimeRange & SetupUIFilters, + setup: Setup & SetupTimeRange, serviceName: string, serviceNodeName?: string ) { diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/index.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/index.ts index 21caab6590fc4..d4084701f0f49 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/index.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/index.ts @@ -5,11 +5,7 @@ */ import { getHeapMemoryChart } from './heap_memory'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../helpers/setup_request'; import { getNonHeapMemoryChart } from './non_heap_memory'; import { getThreadCountChart } from './thread_count'; import { getCPUChartData } from '../shared/cpu'; @@ -18,7 +14,7 @@ import { getGcRateChart } from './gc/get_gc_rate_chart'; import { getGcTimeChart } from './gc/get_gc_time_chart'; export async function getJavaMetricsCharts( - setup: Setup & SetupTimeRange & SetupUIFilters, + setup: Setup & SetupTimeRange, serviceName: string, serviceNodeName?: string ) { diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/non_heap_memory/index.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/non_heap_memory/index.ts index 1a2d5bd0b0e68..50cc449da3c15 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/non_heap_memory/index.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/non_heap_memory/index.ts @@ -12,11 +12,7 @@ import { METRIC_JAVA_NON_HEAP_MEMORY_USED, AGENT_NAME, } from '../../../../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../../helpers/setup_request'; import { ChartBase } from '../../../types'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; @@ -52,7 +48,7 @@ const chartBase: ChartBase = { }; export async function getNonHeapMemoryChart( - setup: Setup & SetupUIFilters & SetupTimeRange, + setup: Setup & SetupTimeRange, serviceName: string, serviceNodeName?: string ) { diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/thread_count/index.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/thread_count/index.ts index 01cc6d8495244..0062f0a423970 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/java/thread_count/index.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/java/thread_count/index.ts @@ -10,11 +10,7 @@ import { METRIC_JAVA_THREAD_COUNT, AGENT_NAME, } from '../../../../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../../helpers/setup_request'; import { ChartBase } from '../../../types'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; @@ -44,7 +40,7 @@ const chartBase: ChartBase = { }; export async function getThreadCountChart( - setup: Setup & SetupTimeRange & SetupUIFilters, + setup: Setup & SetupTimeRange, serviceName: string, serviceNodeName?: string ) { diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/shared/cpu/index.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/shared/cpu/index.ts index 066ef40b4ab6c..ca642aa12fff1 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/shared/cpu/index.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/shared/cpu/index.ts @@ -10,11 +10,7 @@ import { METRIC_SYSTEM_CPU_PERCENT, METRIC_PROCESS_CPU_PERCENT, } from '../../../../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../../helpers/setup_request'; import { ChartBase } from '../../../types'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; @@ -56,7 +52,7 @@ const chartBase: ChartBase = { }; export async function getCPUChartData( - setup: Setup & SetupTimeRange & SetupUIFilters, + setup: Setup & SetupTimeRange, serviceName: string, serviceNodeName?: string ) { diff --git a/x-pack/plugins/apm/server/lib/metrics/by_agent/shared/memory/index.ts b/x-pack/plugins/apm/server/lib/metrics/by_agent/shared/memory/index.ts index a60576ca0c175..e6ee47cc815ef 100644 --- a/x-pack/plugins/apm/server/lib/metrics/by_agent/shared/memory/index.ts +++ b/x-pack/plugins/apm/server/lib/metrics/by_agent/shared/memory/index.ts @@ -11,11 +11,7 @@ import { METRIC_SYSTEM_FREE_MEMORY, METRIC_SYSTEM_TOTAL_MEMORY, } from '../../../../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../../helpers/setup_request'; import { fetchAndTransformMetrics } from '../../../fetch_and_transform_metrics'; import { ChartBase } from '../../../types'; @@ -54,7 +50,7 @@ export const percentCgroupMemoryUsedScript = { lang: 'painless', source: ` /* - When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. + When no limit is specified in the container, docker allows the app as much memory / swap memory as it wants. This number represents the max possible value for the limit field. */ double CGROUP_LIMIT_MAX_VALUE = 9223372036854771712L; @@ -73,7 +69,7 @@ export const percentCgroupMemoryUsedScript = { }; export async function getMemoryChartData( - setup: Setup & SetupTimeRange & SetupUIFilters, + setup: Setup & SetupTimeRange, serviceName: string, serviceNodeName?: string ) { diff --git a/x-pack/plugins/apm/server/lib/metrics/fetch_and_transform_metrics.ts b/x-pack/plugins/apm/server/lib/metrics/fetch_and_transform_metrics.ts index a42a10d6518a0..3ccba8c7586dc 100644 --- a/x-pack/plugins/apm/server/lib/metrics/fetch_and_transform_metrics.ts +++ b/x-pack/plugins/apm/server/lib/metrics/fetch_and_transform_metrics.ts @@ -5,11 +5,7 @@ */ import { Unionize, Overwrite } from 'utility-types'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getMetricsDateHistogramParams } from '../helpers/metrics'; import { ChartBase } from './types'; import { transformDataToMetricsChart } from './transform_metrics_chart'; @@ -58,7 +54,7 @@ export async function fetchAndTransformMetrics({ aggs, additionalFilters = [], }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; serviceName: string; serviceNodeName?: string; chartBase: ChartBase; diff --git a/x-pack/plugins/apm/server/lib/metrics/get_metrics_chart_data_by_agent.ts b/x-pack/plugins/apm/server/lib/metrics/get_metrics_chart_data_by_agent.ts index 059e1ce48c83d..72cd65deebff6 100644 --- a/x-pack/plugins/apm/server/lib/metrics/get_metrics_chart_data_by_agent.ts +++ b/x-pack/plugins/apm/server/lib/metrics/get_metrics_chart_data_by_agent.ts @@ -3,11 +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 { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getJavaMetricsCharts } from './by_agent/java'; import { getDefaultMetricsCharts } from './by_agent/default'; import { GenericMetricsChart } from './transform_metrics_chart'; @@ -22,7 +18,7 @@ export async function getMetricsChartDataByAgent({ serviceNodeName, agentName, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; serviceName: string; serviceNodeName?: string; agentName: string; diff --git a/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap index 66cfa954965d2..1fafa08082443 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/rum_client/__snapshots__/queries.test.ts.snap @@ -61,7 +61,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -151,7 +151,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -167,27 +167,42 @@ exports[`rum client dashboard queries fetches long task metrics 1`] = ` Object { "apm": Object { "events": Array [ - "span", + "transaction", ], }, "body": Object { "aggs": Object { - "transIds": Object { - "aggs": Object { - "longestLongTask": Object { - "max": Object { - "field": "span.duration.us", - }, + "longTaskCount": Object { + "percentiles": Object { + "field": "transaction.experience.longtask.count", + "hdr": Object { + "number_of_significant_value_digits": 3, }, - "sumLongTask": Object { - "sum": Object { - "field": "span.duration.us", - }, + "percents": Array [ + 50, + ], + }, + }, + "longTaskMax": Object { + "percentiles": Object { + "field": "transaction.experience.longtask.max", + "hdr": Object { + "number_of_significant_value_digits": 3, }, + "percents": Array [ + 50, + ], }, - "terms": Object { - "field": "transaction.id", - "size": 1000, + }, + "longTaskSum": Object { + "percentiles": Object { + "field": "transaction.experience.longtask.sum", + "hdr": Object { + "number_of_significant_value_digits": 3, + }, + "percents": Array [ + 50, + ], }, }, }, @@ -205,12 +220,17 @@ Object { }, Object { "term": Object { - "span.type": "longtask", + "transaction.type": "page-load", + }, + }, + Object { + "exists": Object { + "field": "transaction.marks.navigationTiming.fetchStart", }, }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -245,10 +265,214 @@ Object { ], }, }, - "minDuration": Object { - "min": Object { + "loadDistribution": Object { + "percentile_ranks": Object { "field": "transaction.duration.us", - "missing": 0, + "hdr": Object { + "number_of_significant_value_digits": 3, + }, + "keyed": false, + "values": Array [ + 0, + 500000, + 1000000, + 1500000, + 2000000, + 2500000, + 3000000, + 3500000, + 4000000, + 4500000, + 5000000, + 5500000, + 6000000, + 6500000, + 7000000, + 7500000, + 8000000, + 8500000, + 9000000, + 9500000, + 10000000, + 10500000, + 11000000, + 11500000, + 12000000, + 12500000, + 13000000, + 13500000, + 14000000, + 14500000, + 15000000, + 15500000, + 16000000, + 16500000, + 17000000, + 17500000, + 18000000, + 18500000, + 19000000, + 19500000, + 20000000, + 20500000, + 21000000, + 21500000, + 22000000, + 22500000, + 23000000, + 23500000, + 24000000, + 24500000, + 25000000, + 25500000, + 26000000, + 26500000, + 27000000, + 27500000, + 28000000, + 28500000, + 29000000, + 29500000, + 30000000, + 30500000, + 31000000, + 31500000, + 32000000, + 32500000, + 33000000, + 33500000, + 34000000, + 34500000, + 35000000, + 35500000, + 36000000, + 36500000, + 37000000, + 37500000, + 38000000, + 38500000, + 39000000, + 39500000, + 40000000, + 40500000, + 41000000, + 41500000, + 42000000, + 42500000, + 43000000, + 43500000, + 44000000, + 44500000, + 45000000, + 45500000, + 46000000, + 46500000, + 47000000, + 47500000, + 48000000, + 48500000, + 49000000, + 49500000, + 50000000, + 50500000, + 51000000, + 51500000, + 52000000, + 52500000, + 53000000, + 53500000, + 54000000, + 54500000, + 55000000, + 55500000, + 56000000, + 56500000, + 57000000, + 57500000, + 58000000, + 58500000, + 59000000, + 59500000, + 60000000, + 60500000, + 61000000, + 61500000, + 62000000, + 62500000, + 63000000, + 63500000, + 64000000, + 64500000, + 65000000, + 65500000, + 66000000, + 66500000, + 67000000, + 67500000, + 68000000, + 68500000, + 69000000, + 69500000, + 70000000, + 70500000, + 71000000, + 71500000, + 72000000, + 72500000, + 73000000, + 73500000, + 74000000, + 74500000, + 75000000, + 75500000, + 76000000, + 76500000, + 77000000, + 77500000, + 78000000, + 78500000, + 79000000, + 79500000, + 80000000, + 80500000, + 81000000, + 81500000, + 82000000, + 82500000, + 83000000, + 83500000, + 84000000, + 84500000, + 85000000, + 85500000, + 86000000, + 86500000, + 87000000, + 87500000, + 88000000, + 88500000, + 89000000, + 89500000, + 90000000, + 90500000, + 91000000, + 91500000, + 92000000, + 92500000, + 93000000, + 93500000, + 94000000, + 94500000, + 95000000, + 95500000, + 96000000, + 96500000, + 97000000, + 97500000, + 98000000, + 98500000, + 99000000, + ], }, }, }, @@ -276,7 +500,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -328,7 +552,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -443,7 +667,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -499,7 +723,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_client_metrics.ts b/x-pack/plugins/apm/server/lib/rum_client/get_client_metrics.ts index a210c32ceb44e..6d596246d6af9 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_client_metrics.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_client_metrics.ts @@ -7,11 +7,7 @@ import { TRANSACTION_DURATION } from '../../../common/elasticsearch_fieldnames'; import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; import { mergeProjection } from '../../projections/util/merge_projection'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { TRANSACTION_DOM_INTERACTIVE, TRANSACTION_TIME_TO_FIRST_BYTE, @@ -22,7 +18,7 @@ export async function getClientMetrics({ urlQuery, percentile = 50, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; urlQuery?: string; percentile?: number; }) { @@ -72,11 +68,9 @@ export async function getClientMetrics({ // Divide by 1000 to convert ms into seconds return { pageViews, - backEnd: { value: (backEnd.values[pkey] || 0) / 1000 }, + backEnd: { value: backEnd.values[pkey] || 0 }, frontEnd: { - value: - ((domInteractive.values[pkey] || 0) - (backEnd.values[pkey] || 0)) / - 1000, + value: (domInteractive.values[pkey] || 0) - (backEnd.values[pkey] || 0), }, }; } diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_js_errors.ts b/x-pack/plugins/apm/server/lib/rum_client/get_js_errors.ts index 0540ea4bf09dd..a8a4e2714c86e 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_js_errors.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_js_errors.ts @@ -5,11 +5,7 @@ */ import { mergeProjection } from '../../projections/util/merge_projection'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getRumErrorsProjection } from '../../projections/rum_page_load_transactions'; import { ERROR_EXC_MESSAGE, @@ -23,7 +19,7 @@ export async function getJSErrors({ pageSize, pageIndex, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; pageSize: number; pageIndex: number; }) { diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_long_task_metrics.ts b/x-pack/plugins/apm/server/lib/rum_client/get_long_task_metrics.ts index bd4bdb9ca3536..dfb31de8f10f7 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_long_task_metrics.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_long_task_metrics.ts @@ -4,51 +4,56 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - getRumLongTasksProjection, - getRumPageLoadTransactionsProjection, -} from '../../projections/rum_page_load_transactions'; +import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; import { mergeProjection } from '../../projections/util/merge_projection'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; -import { - SPAN_DURATION, - TRANSACTION_ID, -} from '../../../common/elasticsearch_fieldnames'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; + +const LONG_TASK_SUM_FIELD = 'transaction.experience.longtask.sum'; +const LONG_TASK_COUNT_FIELD = 'transaction.experience.longtask.count'; +const LONG_TASK_MAX_FIELD = 'transaction.experience.longtask.max'; export async function getLongTaskMetrics({ setup, urlQuery, + percentile = 50, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; urlQuery?: string; + percentile?: number; }) { - const projection = getRumLongTasksProjection({ + const projection = getRumPageLoadTransactionsProjection({ setup, + urlQuery, }); const params = mergeProjection(projection, { body: { size: 0, aggs: { - transIds: { - terms: { - field: 'transaction.id', - size: 1000, + longTaskSum: { + percentiles: { + field: LONG_TASK_SUM_FIELD, + percents: [percentile], + hdr: { + number_of_significant_value_digits: 3, + }, }, - aggs: { - sumLongTask: { - sum: { - field: SPAN_DURATION, - }, + }, + longTaskCount: { + percentiles: { + field: LONG_TASK_COUNT_FIELD, + percents: [percentile], + hdr: { + number_of_significant_value_digits: 3, }, - longestLongTask: { - max: { - field: SPAN_DURATION, - }, + }, + }, + longTaskMax: { + percentiles: { + field: LONG_TASK_MAX_FIELD, + percents: [percentile], + hdr: { + number_of_significant_value_digits: 3, }, }, }, @@ -59,71 +64,15 @@ export async function getLongTaskMetrics({ const { apmEventClient } = setup; const response = await apmEventClient.search(params); - const { transIds } = response.aggregations ?? {}; - const validTransactions: string[] = await filterPageLoadTransactions({ - setup, - urlQuery, - transactionIds: (transIds?.buckets ?? []).map( - (bucket) => bucket.key as string - ), - }); - let noOfLongTasks = 0; - let sumOfLongTasks = 0; - let longestLongTask = 0; + const pkey = percentile.toFixed(1); - (transIds?.buckets ?? []).forEach((bucket) => { - if (validTransactions.includes(bucket.key as string)) { - noOfLongTasks += bucket.doc_count; - sumOfLongTasks += bucket.sumLongTask.value ?? 0; - if ((bucket.longestLongTask.value ?? 0) > longestLongTask) { - longestLongTask = bucket.longestLongTask.value!; - } - } - }); + const { longTaskSum, longTaskCount, longTaskMax } = + response.aggregations ?? {}; return { - noOfLongTasks, - sumOfLongTasks, - longestLongTask, + noOfLongTasks: longTaskCount?.values[pkey] ?? 0, + sumOfLongTasks: longTaskSum?.values[pkey] ?? 0, + longestLongTask: longTaskMax?.values[pkey] ?? 0, }; } - -async function filterPageLoadTransactions({ - setup, - urlQuery, - transactionIds, -}: { - setup: Setup & SetupTimeRange & SetupUIFilters; - urlQuery?: string; - transactionIds: string[]; -}) { - const projection = getRumPageLoadTransactionsProjection({ - setup, - urlQuery, - }); - - const params = mergeProjection(projection, { - body: { - size: transactionIds.length, - query: { - bool: { - must: [ - { - terms: { - [TRANSACTION_ID]: transactionIds, - }, - }, - ], - filter: [...projection.body.query.bool.filter], - }, - }, - _source: [TRANSACTION_ID], - }, - }); - - const { apmEventClient } = setup; - - const response = await apmEventClient.search(params); - return response.hits.hits.map((hit) => (hit._source as any).transaction.id)!; -} diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts b/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts index 25de9f06fefc4..225afff2818ab 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_page_load_distribution.ts @@ -7,16 +7,10 @@ import { TRANSACTION_DURATION } from '../../../common/elasticsearch_fieldnames'; import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; import { mergeProjection } from '../../projections/util/merge_projection'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; export const MICRO_TO_SEC = 1000000; -const NUMBER_OF_PLD_STEPS = 100; - export function microToSec(val: number) { return Math.round((val / MICRO_TO_SEC + Number.EPSILON) * 100) / 100; } @@ -24,15 +18,31 @@ export function microToSec(val: number) { export const getPLDChartSteps = ({ maxDuration, minDuration, + initStepValue, }: { maxDuration: number; minDuration: number; + initStepValue?: number; }) => { - const stepValue = (maxDuration - minDuration) / NUMBER_OF_PLD_STEPS; - const stepValues = []; - for (let i = 1; i < NUMBER_OF_PLD_STEPS + 1; i++) { - stepValues.push((stepValue * i + minDuration).toFixed(2)); + let stepValue = 0.5; + // if diff is too low, let's lower + // down the steps value to increase steps + if (maxDuration - minDuration <= 5 * MICRO_TO_SEC) { + stepValue = 0.1; + } + + if (initStepValue) { + stepValue = initStepValue; + } + + let initValue = minDuration; + const stepValues = [initValue]; + + while (initValue < maxDuration) { + initValue += stepValue * MICRO_TO_SEC; + stepValues.push(initValue); } + return stepValues; }; @@ -42,7 +52,7 @@ export async function getPageLoadDistribution({ maxPercentile, urlQuery, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; minPercentile?: string; maxPercentile?: string; urlQuery?: string; @@ -52,16 +62,21 @@ export async function getPageLoadDistribution({ urlQuery, }); + // we will first get 100 steps using 0sec and 50sec duration, + // most web apps will cover this use case + // if 99th percentile is greater than 50sec, + // we will fetch additional 5 steps beyond 99th percentile + let maxDuration = (maxPercentile ? +maxPercentile : 50) * MICRO_TO_SEC; + const minDuration = minPercentile ? +minPercentile * MICRO_TO_SEC : 0; + const stepValues = getPLDChartSteps({ + maxDuration, + minDuration, + }); + const params = mergeProjection(projection, { body: { size: 0, aggs: { - minDuration: { - min: { - field: TRANSACTION_DURATION, - missing: 0, - }, - }, durPercentiles: { percentiles: { field: TRANSACTION_DURATION, @@ -71,6 +86,16 @@ export async function getPageLoadDistribution({ }, }, }, + loadDistribution: { + percentile_ranks: { + field: TRANSACTION_DURATION, + values: stepValues, + keyed: false, + hdr: { + number_of_significant_value_digits: 3, + }, + }, + }, }, }, }); @@ -86,22 +111,40 @@ export async function getPageLoadDistribution({ return null; } - const { durPercentiles, minDuration } = aggregations ?? {}; + const { durPercentiles, loadDistribution } = aggregations ?? {}; - const minPerc = minPercentile - ? +minPercentile * MICRO_TO_SEC - : minDuration?.value ?? 0; + let pageDistVals = loadDistribution?.values ?? []; - const maxPercQuery = durPercentiles?.values['99.0'] ?? 10000; + const maxPercQuery = durPercentiles?.values['99.0'] ?? 0; - const maxPerc = maxPercentile ? +maxPercentile * MICRO_TO_SEC : maxPercQuery; + // we assumed that page load will never exceed 50secs, if 99th percentile is + // greater then let's fetch additional 10 steps, to cover that on the chart + if (maxPercQuery > maxDuration && !maxPercentile) { + const additionalStepsPageVals = await getPercentilesDistribution({ + setup, + maxDuration: maxPercQuery, + // we pass 50sec as min to get next steps + minDuration: maxDuration, + }); - const pageDist = await getPercentilesDistribution({ - setup, - minDuration: minPerc, - maxDuration: maxPerc, + pageDistVals = pageDistVals.concat(additionalStepsPageVals); + maxDuration = maxPercQuery; + } + + // calculate the diff to get actual page load on specific duration value + const pageDist = pageDistVals.map(({ key, value }, index: number, arr) => { + return { + x: microToSec(key), + y: index === 0 ? value : value - arr[index - 1].value, + }; }); + if (pageDist.length > 0) { + while (pageDist[pageDist.length - 1].y === 0) { + pageDist.pop(); + } + } + Object.entries(durPercentiles?.values ?? {}).forEach(([key, val]) => { if (durPercentiles?.values?.[key]) { durPercentiles.values[key] = microToSec(val as number); @@ -111,8 +154,8 @@ export async function getPageLoadDistribution({ return { pageLoadDistribution: pageDist, percentiles: durPercentiles?.values, - minDuration: microToSec(minPerc), - maxDuration: microToSec(maxPerc), + minDuration: microToSec(minDuration), + maxDuration: microToSec(maxDuration), }; } @@ -121,11 +164,15 @@ const getPercentilesDistribution = async ({ minDuration, maxDuration, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; minDuration: number; maxDuration: number; }) => { - const stepValues = getPLDChartSteps({ maxDuration, minDuration }); + const stepValues = getPLDChartSteps({ + minDuration: minDuration + 0.5 * MICRO_TO_SEC, + maxDuration, + initStepValue: 0.5, + }); const projection = getRumPageLoadTransactionsProjection({ setup, @@ -153,12 +200,5 @@ const getPercentilesDistribution = async ({ const { aggregations } = await apmEventClient.search(params); - const pageDist = aggregations?.loadDistribution.values ?? []; - - return pageDist.map(({ key, value }, index: number, arr) => { - return { - x: microToSec(key), - y: index === 0 ? value : value - arr[index - 1].value, - }; - }); + return aggregations?.loadDistribution.values ?? []; }; diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts index 40f8a8bc58a54..c1a602c33feae 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_page_view_trends.ts @@ -5,11 +5,7 @@ */ import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; import { mergeProjection } from '../../projections/util/merge_projection'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { BreakdownItem } from '../../../typings/ui_filters'; export async function getPageViewTrends({ @@ -17,7 +13,7 @@ export async function getPageViewTrends({ breakdowns, urlQuery, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; breakdowns?: string; urlQuery?: string; }) { diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_pl_dist_breakdown.ts b/x-pack/plugins/apm/server/lib/rum_client/get_pl_dist_breakdown.ts index d59817cc682a9..e2ec59d232b21 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_pl_dist_breakdown.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_pl_dist_breakdown.ts @@ -7,11 +7,7 @@ import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; import { ProcessorEvent } from '../../../common/processor_event'; import { mergeProjection } from '../../projections/util/merge_projection'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { CLIENT_GEO_COUNTRY_ISO_CODE, USER_AGENT_DEVICE, @@ -41,21 +37,21 @@ export const getBreakdownField = (breakdown: string) => { export const getPageLoadDistBreakdown = async ({ setup, - minDuration, - maxDuration, + minPercentile, + maxPercentile, breakdown, urlQuery, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; - minDuration: number; - maxDuration: number; + setup: Setup & SetupTimeRange; + minPercentile: number; + maxPercentile: number; breakdown: string; urlQuery?: string; }) => { // convert secs to micros const stepValues = getPLDChartSteps({ - minDuration: minDuration * MICRO_TO_SEC, - maxDuration: maxDuration * MICRO_TO_SEC, + maxDuration: (maxPercentile ? +maxPercentile : 50) * MICRO_TO_SEC, + minDuration: minPercentile ? +minPercentile * MICRO_TO_SEC : 0, }); const projection = getRumPageLoadTransactionsProjection({ diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_rum_services.ts b/x-pack/plugins/apm/server/lib/rum_client/get_rum_services.ts index 3adad0868ed4b..e9bd203e354cb 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_rum_services.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_rum_services.ts @@ -5,18 +5,14 @@ */ import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; import { mergeProjection } from '../../projections/util/merge_projection'; export async function getRumServices({ setup, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; }) { const projection = getRumPageLoadTransactionsProjection({ setup, diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_url_search.ts b/x-pack/plugins/apm/server/lib/rum_client/get_url_search.ts index 6aa39c7ef961f..febfd66897e18 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_url_search.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_url_search.ts @@ -5,11 +5,7 @@ */ import { mergeProjection } from '../../projections/util/merge_projection'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; import { TRANSACTION_DURATION, @@ -21,7 +17,7 @@ export async function getUrlSearch({ urlQuery, percentile, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; urlQuery?: string; percentile: number; }) { diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_visitor_breakdown.ts b/x-pack/plugins/apm/server/lib/rum_client/get_visitor_breakdown.ts index 52d089e4e29c9..6350bc2c07016 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_visitor_breakdown.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_visitor_breakdown.ts @@ -6,11 +6,7 @@ import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; import { mergeProjection } from '../../projections/util/merge_projection'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { USER_AGENT_NAME, USER_AGENT_OS, @@ -20,7 +16,7 @@ export async function getVisitorBreakdown({ setup, urlQuery, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; urlQuery?: string; }) { const projection = getRumPageLoadTransactionsProjection({ diff --git a/x-pack/plugins/apm/server/lib/rum_client/get_web_core_vitals.ts b/x-pack/plugins/apm/server/lib/rum_client/get_web_core_vitals.ts index 676b3506397a7..c5baf0b529eb4 100644 --- a/x-pack/plugins/apm/server/lib/rum_client/get_web_core_vitals.ts +++ b/x-pack/plugins/apm/server/lib/rum_client/get_web_core_vitals.ts @@ -6,11 +6,7 @@ import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; import { mergeProjection } from '../../projections/util/merge_projection'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { CLS_FIELD, FCP_FIELD, @@ -25,7 +21,7 @@ export async function getWebCoreVitals({ urlQuery, percentile = 50, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; urlQuery?: string; percentile?: number; }) { diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts index 75acebe7ed56c..330bb936c9e88 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map.ts @@ -82,7 +82,7 @@ async function getServicesData(options: IEnvOptions) { const { setup, searchAggregatedTransactions } = options; const projection = getServicesProjection({ - setup: { ...setup, uiFiltersES: [] }, + setup: { ...setup, esFilter: [] }, searchAggregatedTransactions, }); diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.test.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.test.ts index 7af1607697ef3..eb2ddbf38b274 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.test.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.test.ts @@ -19,11 +19,10 @@ describe('getServiceMapServiceNodeInfo', () => { }), }, indices: {}, + uiFilters: { environment: 'test environment' }, } as unknown) as Setup & SetupTimeRange; - const environment = 'test environment'; const serviceName = 'test service name'; const result = await getServiceMapServiceNodeInfo({ - uiFilters: { environment }, setup, serviceName, searchAggregatedTransactions: false, @@ -67,11 +66,10 @@ describe('getServiceMapServiceNodeInfo', () => { config: { 'xpack.apm.metricsInterval': 30, }, + uiFilters: { environment: 'test environment' }, } as unknown) as Setup & SetupTimeRange; - const environment = 'test environment'; const serviceName = 'test service name'; const result = await getServiceMapServiceNodeInfo({ - uiFilters: { environment }, setup, serviceName, searchAggregatedTransactions: false, diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts index 7c2137ce65d83..37b34641435fb 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts @@ -8,7 +8,6 @@ import { TRANSACTION_REQUEST, TRANSACTION_PAGE_LOAD, } from '../../../common/transaction_types'; -import { UIFilters } from '../../../typings/ui_filters'; import { SERVICE_NAME, METRIC_SYSTEM_CPU_PERCENT, @@ -53,9 +52,8 @@ export async function getServiceMapServiceNodeInfo({ serviceName, setup, searchAggregatedTransactions, - uiFilters, -}: Options & { serviceName: string; uiFilters: UIFilters }) { - const { start, end } = setup; +}: Options & { serviceName: string }) { + const { start, end, uiFilters } = setup; const filter: ESFilter[] = [ { range: rangeFilter(start, end) }, @@ -105,7 +103,8 @@ async function getErrorStats({ }) { const setupWithBlankUiFilters = { ...setup, - uiFiltersES: getEnvironmentUiFilterES(environment), + uiFilters: { environment }, + esFilter: getEnvironmentUiFilterES(environment), }; const { noHits, average } = await getErrorRate({ setup: setupWithBlankUiFilters, diff --git a/x-pack/plugins/apm/server/lib/service_map/mock_responses/group_resource_nodes_grouped.json b/x-pack/plugins/apm/server/lib/service_map/mock_responses/group_resource_nodes_grouped.json index e7bba585de180..94c508fe90230 100644 --- a/x-pack/plugins/apm/server/lib/service_map/mock_responses/group_resource_nodes_grouped.json +++ b/x-pack/plugins/apm/server/lib/service_map/mock_responses/group_resource_nodes_grouped.json @@ -3,7 +3,7 @@ { "data": { "id": "opbeans-rum", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-rum", "agent.name": "rum-js" } @@ -18,7 +18,7 @@ { "data": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" } diff --git a/x-pack/plugins/apm/server/lib/service_map/mock_responses/group_resource_nodes_pregrouped.json b/x-pack/plugins/apm/server/lib/service_map/mock_responses/group_resource_nodes_pregrouped.json index 22c5c50de7472..58469f607ac13 100644 --- a/x-pack/plugins/apm/server/lib/service_map/mock_responses/group_resource_nodes_pregrouped.json +++ b/x-pack/plugins/apm/server/lib/service_map/mock_responses/group_resource_nodes_pregrouped.json @@ -3,7 +3,7 @@ { "data": { "id": "opbeans-rum", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-rum", "agent.name": "rum-js" } @@ -18,7 +18,7 @@ { "data": { "id": "opbeans-node", - "service.environment": "testing", + "service.environment": "test", "service.name": "opbeans-node", "agent.name": "nodejs" } diff --git a/x-pack/plugins/apm/server/lib/service_nodes/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/service_nodes/__snapshots__/queries.test.ts.snap index 87aca0d056909..d83e558775be4 100644 --- a/x-pack/plugins/apm/server/lib/service_nodes/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/service_nodes/__snapshots__/queries.test.ts.snap @@ -51,7 +51,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -119,7 +119,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -188,7 +188,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], diff --git a/x-pack/plugins/apm/server/lib/service_nodes/index.ts b/x-pack/plugins/apm/server/lib/service_nodes/index.ts index a83aba192dba9..d5e29532e3d7b 100644 --- a/x-pack/plugins/apm/server/lib/service_nodes/index.ts +++ b/x-pack/plugins/apm/server/lib/service_nodes/index.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getServiceNodesProjection } from '../../projections/service_nodes'; import { mergeProjection } from '../../projections/util/merge_projection'; import { SERVICE_NODE_NAME_MISSING } from '../../../common/service_nodes'; @@ -23,7 +19,7 @@ const getServiceNodes = async ({ setup, serviceName, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; serviceName: string; }) => { const { apmEventClient } = setup; diff --git a/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap index 431f11066aaff..3a38f80c87b35 100644 --- a/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/services/__snapshots__/queries.test.ts.snap @@ -144,7 +144,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -194,7 +194,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -257,7 +257,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -334,7 +334,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -389,7 +389,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], diff --git a/x-pack/plugins/apm/server/lib/services/get_service_node_metadata.ts b/x-pack/plugins/apm/server/lib/services/get_service_node_metadata.ts index fca472b0ce8c2..d6ba9f5447ba5 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_node_metadata.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_node_metadata.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { HOST_NAME, CONTAINER_ID, @@ -24,7 +20,7 @@ export async function getServiceNodeMetadata({ }: { serviceName: string; serviceNodeName: string; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; }) { const { apmEventClient } = setup; diff --git a/x-pack/plugins/apm/server/lib/services/get_services/get_services_items.ts b/x-pack/plugins/apm/server/lib/services/get_services/get_services_items.ts index c09be7aacc784..092485c46fb08 100644 --- a/x-pack/plugins/apm/server/lib/services/get_services/get_services_items.ts +++ b/x-pack/plugins/apm/server/lib/services/get_services/get_services_items.ts @@ -5,11 +5,7 @@ */ import { joinByKey } from '../../../../common/utils/join_by_key'; import { PromiseReturnType } from '../../../../typings/common'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; import { getServicesProjection } from '../../../projections/services'; import { getTransactionDurationAverages, @@ -21,17 +17,15 @@ import { } from './get_services_items_stats'; export type ServiceListAPIResponse = PromiseReturnType; -export type ServicesItemsSetup = Setup & SetupTimeRange & SetupUIFilters; +export type ServicesItemsSetup = Setup & SetupTimeRange; export type ServicesItemsProjection = ReturnType; export async function getServicesItems({ setup, searchAggregatedTransactions, - mlAnomaliesEnvironment, }: { setup: ServicesItemsSetup; searchAggregatedTransactions: boolean; - mlAnomaliesEnvironment?: string; }) { const params = { projection: getServicesProjection({ @@ -55,7 +49,7 @@ export async function getServicesItems({ getTransactionRates(params), getTransactionErrorRates(params), getEnvironments(params), - getHealthStatuses(params, mlAnomaliesEnvironment), + getHealthStatuses(params, setup.uiFilters.environment), ]); const allMetrics = [ diff --git a/x-pack/plugins/apm/server/lib/services/get_services/index.ts b/x-pack/plugins/apm/server/lib/services/get_services/index.ts index 351457b2a815e..04744a9c791bb 100644 --- a/x-pack/plugins/apm/server/lib/services/get_services/index.ts +++ b/x-pack/plugins/apm/server/lib/services/get_services/index.ts @@ -6,11 +6,7 @@ import { isEmpty } from 'lodash'; import { PromiseReturnType } from '../../../../typings/common'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; import { hasHistoricalAgentData } from './has_historical_agent_data'; import { getLegacyDataStatus } from './get_legacy_data_status'; import { getServicesItems } from './get_services_items'; @@ -20,17 +16,14 @@ export type ServiceListAPIResponse = PromiseReturnType; export async function getServices({ setup, searchAggregatedTransactions, - mlAnomaliesEnvironment, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; searchAggregatedTransactions: boolean; - mlAnomaliesEnvironment?: string; }) { const [items, hasLegacyData] = await Promise.all([ getServicesItems({ setup, searchAggregatedTransactions, - mlAnomaliesEnvironment, }), getLegacyDataStatus(setup), ]); diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap index bd6cefa793467..c678e7db711b6 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/transaction_groups/__snapshots__/queries.test.ts.snap @@ -61,7 +61,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -128,7 +128,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -195,7 +195,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -270,7 +270,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -325,7 +325,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -380,7 +380,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -441,7 +441,7 @@ Array [ }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts b/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts index 5d581149db667..0a4d9748f2597 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts @@ -15,11 +15,7 @@ import { getTransactionGroupsProjection } from '../../projections/transaction_gr import { mergeProjection } from '../../projections/util/merge_projection'; import { PromiseReturnType } from '../../../../observability/typings/common'; import { AggregationOptionsByType } from '../../../typings/elasticsearch/aggregations'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getAverages, getSums, @@ -57,7 +53,7 @@ export type TransactionGroupRequestBase = ReturnType< }; }; -export type TransactionGroupSetup = Setup & SetupTimeRange & SetupUIFilters; +export type TransactionGroupSetup = Setup & SetupTimeRange; function getItemsWithRelativeImpact( setup: TransactionGroupSetup, diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts b/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts index 3dc126c45d328..d5289430b2698 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts @@ -12,11 +12,7 @@ import { EVENT_OUTCOME, } from '../../../common/elasticsearch_fieldnames'; import { rangeFilter } from '../../../common/utils/range_filter'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { getBucketSize } from '../helpers/get_bucket_size'; import { getProcessorEventForAggregatedTransactions, @@ -33,10 +29,10 @@ export async function getErrorRate({ serviceName: string; transactionType?: string; transactionName?: string; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; searchAggregatedTransactions: boolean; }) { - const { start, end, uiFiltersES, apmEventClient } = setup; + const { start, end, esFilter, apmEventClient } = setup; const transactionNamefilter = transactionName ? [{ term: { [TRANSACTION_NAME]: transactionName } }] @@ -53,7 +49,7 @@ export async function getErrorRate({ }, ...transactionNamefilter, ...transactionTypefilter, - ...uiFiltersES, + ...esFilter, ]; const params = { diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_sample_for_group.ts b/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_sample_for_group.ts index 6c9b23b3dc079..7e1aad075fb16 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_sample_for_group.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_sample_for_group.ts @@ -12,11 +12,7 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { ProcessorEvent } from '../../../common/processor_event'; import { rangeFilter } from '../../../common/utils/range_filter'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; export async function getTransactionSampleForGroup({ serviceName, @@ -25,9 +21,9 @@ export async function getTransactionSampleForGroup({ }: { serviceName: string; transactionName: string; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; }) { - const { apmEventClient, start, end, uiFiltersES } = setup; + const { apmEventClient, start, end, esFilter } = setup; const filter = [ { @@ -43,7 +39,7 @@ export async function getTransactionSampleForGroup({ [TRANSACTION_NAME]: transactionName, }, }, - ...uiFiltersES, + ...esFilter, ]; const getSampledTransaction = async () => { diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/index.ts b/x-pack/plugins/apm/server/lib/transaction_groups/index.ts index 6e0d619268d44..3796511029243 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/index.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/index.ts @@ -4,16 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../helpers/setup_request'; import { transactionGroupsFetcher, Options } from './fetcher'; export async function getTransactionGroupList( options: Options, - setup: Setup & SetupTimeRange & SetupUIFilters + setup: Setup & SetupTimeRange ) { const bucketSize = setup.config['xpack.apm.ui.transactionGroupBucketSize']; return await transactionGroupsFetcher(options, setup, bucketSize); diff --git a/x-pack/plugins/apm/server/lib/transactions/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/transactions/__snapshots__/queries.test.ts.snap index c63dfcc0c0ec7..3e0a7317afd70 100644 --- a/x-pack/plugins/apm/server/lib/transactions/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/transactions/__snapshots__/queries.test.ts.snap @@ -161,7 +161,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -295,7 +295,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -401,7 +401,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], @@ -502,7 +502,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -608,7 +608,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, Object { @@ -673,7 +673,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], diff --git a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts index 34863c64f9804..8bbcaebe06513 100644 --- a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts +++ b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.test.ts @@ -36,7 +36,8 @@ function getMockSetup(esResponse: any) { get: () => 'myIndex', } ) as APMConfig, - uiFiltersES: [], + uiFilters: {}, + esFilter: [], indices: mockIndices, dynamicIndexPattern: null as any, }; diff --git a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts index 9730ddbbf38d7..8febdc898ab97 100644 --- a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts @@ -16,11 +16,7 @@ import { TRANSACTION_NAME, TRANSACTION_BREAKDOWN_COUNT, } from '../../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; import { rangeFilter } from '../../../../common/utils/range_filter'; import { getMetricsDateHistogramParams } from '../../helpers/metrics'; import { MAX_KPIS } from './constants'; @@ -32,12 +28,12 @@ export async function getTransactionBreakdown({ transactionName, transactionType, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; serviceName: string; transactionName?: string; transactionType: string; }) { - const { uiFiltersES, apmEventClient, start, end, config } = setup; + const { esFilter, apmEventClient, start, end, config } = setup; const subAggs = { sum_all_self_times: { @@ -84,7 +80,7 @@ export async function getTransactionBreakdown({ { term: { [SERVICE_NAME]: serviceName } }, { term: { [TRANSACTION_TYPE]: transactionType } }, { range: rangeFilter(start, end) }, - ...uiFiltersES, + ...esFilter, ]; if (transactionName) { diff --git a/x-pack/plugins/apm/server/lib/transactions/charts/get_anomaly_data/fetcher.ts b/x-pack/plugins/apm/server/lib/transactions/charts/get_anomaly_data/fetcher.ts index 3cf9a54e3fe9b..287c7bc2c47f9 100644 --- a/x-pack/plugins/apm/server/lib/transactions/charts/get_anomaly_data/fetcher.ts +++ b/x-pack/plugins/apm/server/lib/transactions/charts/get_anomaly_data/fetcher.ts @@ -5,6 +5,7 @@ */ import { Logger } from 'kibana/server'; +import { ESSearchResponse } from '../../../../../typings/elasticsearch'; import { PromiseReturnType } from '../../../../../../observability/typings/common'; import { Setup, SetupTimeRange } from '../../../helpers/setup_request'; @@ -47,7 +48,7 @@ export async function anomalySeriesFetcher({ filter: [ { term: { job_id: jobId } }, { exists: { field: 'bucket_span' } }, - { term: { result_type: 'model_plot' } }, + { terms: { result_type: ['model_plot', 'record'] } }, { term: { partition_field_value: serviceName } }, { term: { by_field_value: transactionType } }, { @@ -67,7 +68,7 @@ export async function anomalySeriesFetcher({ extended_bounds: { min: newStart, max: end }, }, aggs: { - anomaly_score: { max: { field: 'anomaly_score' } }, + anomaly_score: { max: { field: 'record_score' } }, lower: { min: { field: 'model_lower' } }, upper: { max: { field: 'model_upper' } }, }, @@ -77,7 +78,11 @@ export async function anomalySeriesFetcher({ }; try { - const response = await ml.mlSystem.mlAnomalySearch(params); + const response: ESSearchResponse< + unknown, + typeof params + > = (await ml.mlSystem.mlAnomalySearch(params)) as any; + return response; } catch (err) { const isHttpError = 'statusCode' in err; diff --git a/x-pack/plugins/apm/server/lib/transactions/charts/get_anomaly_data/index.ts b/x-pack/plugins/apm/server/lib/transactions/charts/get_anomaly_data/index.ts index d8865f0049d35..f11623eaa2dae 100644 --- a/x-pack/plugins/apm/server/lib/transactions/charts/get_anomaly_data/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/charts/get_anomaly_data/index.ts @@ -5,17 +5,13 @@ */ import { Logger } from 'kibana/server'; import { isNumber } from 'lodash'; +import { ENVIRONMENT_ALL } from '../../../../../common/environment_filter_values'; import { getBucketSize } from '../../../helpers/get_bucket_size'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../helpers/setup_request'; import { anomalySeriesFetcher } from './fetcher'; import { getMlBucketSize } from './get_ml_bucket_size'; import { anomalySeriesTransform } from './transform'; import { getMLJobIds } from '../../../service_map/get_service_anomalies'; -import { UIFilters } from '../../../../../typings/ui_filters'; export async function getAnomalySeries({ serviceName, @@ -24,15 +20,13 @@ export async function getAnomalySeries({ timeSeriesDates, setup, logger, - uiFilters, }: { serviceName: string; transactionType: string | undefined; transactionName: string | undefined; timeSeriesDates: number[]; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; logger: Logger; - uiFilters: UIFilters; }) { // don't fetch anomalies for transaction details page if (transactionName) { @@ -44,12 +38,22 @@ export async function getAnomalySeries({ return; } + const { uiFilters, start, end } = setup; + const { environment } = uiFilters; + + // don't fetch anomalies when no specific environment is selected + if (environment === ENVIRONMENT_ALL.value) { + return; + } + // don't fetch anomalies if unknown uiFilters are applied const knownFilters = ['environment', 'serviceName']; - const uiFilterNames = Object.keys(uiFilters); - if ( - uiFilterNames.some((uiFilterName) => !knownFilters.includes(uiFilterName)) - ) { + const hasUnknownFiltersApplied = Object.entries(setup.uiFilters) + .filter(([key, value]) => !!value) + .map(([key]) => key) + .some((uiFilterName) => !knownFilters.includes(uiFilterName)); + + if (hasUnknownFiltersApplied) { return; } @@ -64,15 +68,8 @@ export async function getAnomalySeries({ return; } - const mlJobIds = await getMLJobIds( - setup.ml.anomalyDetectors, - uiFilters.environment - ); + const mlJobIds = await getMLJobIds(setup.ml.anomalyDetectors, environment); - // don't fetch anomalies if there are isn't exaclty 1 ML job match for the given environment - if (mlJobIds.length !== 1) { - return; - } const jobId = mlJobIds[0]; const mlBucketSize = await getMlBucketSize({ setup, jobId, logger }); @@ -80,7 +77,6 @@ export async function getAnomalySeries({ return; } - const { start, end } = setup; const { intervalString, bucketSize } = getBucketSize(start, end); const esResponse = await anomalySeriesFetcher({ diff --git a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts index fdbd99bf274d6..75dfae3e7375f 100644 --- a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts +++ b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.test.ts @@ -29,7 +29,10 @@ describe('timeseriesFetcher', () => { get: () => 'myIndex', } ) as APMConfig, - uiFiltersES: [ + uiFilters: { + environment: 'test', + }, + esFilter: [ { term: { 'service.environment': 'test' }, }, diff --git a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.ts b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.ts index 5a3948f577430..e2edbbec63d47 100644 --- a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.ts +++ b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/fetcher.ts @@ -14,11 +14,7 @@ import { import { PromiseReturnType } from '../../../../../../observability/typings/common'; import { getBucketSize } from '../../../helpers/get_bucket_size'; import { rangeFilter } from '../../../../../common/utils/range_filter'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../helpers/setup_request'; import { getProcessorEventForAggregatedTransactions, getTransactionDurationFieldForAggregatedTransactions, @@ -36,10 +32,10 @@ export function timeseriesFetcher({ serviceName: string; transactionType: string | undefined; transactionName: string | undefined; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; searchAggregatedTransactions: boolean; }) { - const { start, end, uiFiltersES, apmEventClient } = setup; + const { start, end, apmEventClient } = setup; const { intervalString } = getBucketSize(start, end); const filter: ESFilter[] = [ @@ -48,7 +44,7 @@ export function timeseriesFetcher({ ...getDocumentTypeFilterForAggregatedTransactions( searchAggregatedTransactions ), - ...uiFiltersES, + ...setup.esFilter, ]; if (transactionName) { diff --git a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/index.ts b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/index.ts index 81dca447f16ca..c0421005dd06e 100644 --- a/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/charts/get_timeseries_data/index.ts @@ -5,11 +5,7 @@ */ import { getBucketSize } from '../../../helpers/get_bucket_size'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../helpers/setup_request'; import { timeseriesFetcher } from './fetcher'; import { timeseriesTransformer } from './transform'; @@ -17,7 +13,7 @@ export async function getApmTimeseriesData(options: { serviceName: string; transactionType: string | undefined; transactionName: string | undefined; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; searchAggregatedTransactions: boolean; }) { const { start, end } = options.setup; diff --git a/x-pack/plugins/apm/server/lib/transactions/charts/index.ts b/x-pack/plugins/apm/server/lib/transactions/charts/index.ts index 43abf0b1a1d33..d8593612c0582 100644 --- a/x-pack/plugins/apm/server/lib/transactions/charts/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/charts/index.ts @@ -6,15 +6,10 @@ import { Logger } from 'kibana/server'; import { PromiseReturnType } from '../../../../../observability/typings/common'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; import { getAnomalySeries } from './get_anomaly_data'; import { getApmTimeseriesData } from './get_timeseries_data'; import { ApmTimeSeriesResponse } from './get_timeseries_data/transform'; -import { UIFilters } from '../../../../typings/ui_filters'; function getDates(apmTimeseries: ApmTimeSeriesResponse) { return apmTimeseries.responseTimes.avg.map((p) => p.x); @@ -27,10 +22,9 @@ export async function getTransactionCharts(options: { serviceName: string; transactionType: string | undefined; transactionName: string | undefined; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; searchAggregatedTransactions: boolean; logger: Logger; - uiFilters: UIFilters; }) { const apmTimeseries = await getApmTimeseriesData(options); const anomalyTimeseries = await getAnomalySeries({ diff --git a/x-pack/plugins/apm/server/lib/transactions/distribution/get_buckets/index.ts b/x-pack/plugins/apm/server/lib/transactions/distribution/get_buckets/index.ts index 6e2fe34a5f5ef..34d01627a2869 100644 --- a/x-pack/plugins/apm/server/lib/transactions/distribution/get_buckets/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/distribution/get_buckets/index.ts @@ -17,11 +17,7 @@ import { TRANSACTION_TYPE, } from '../../../../../common/elasticsearch_fieldnames'; import { rangeFilter } from '../../../../../common/utils/range_filter'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../../helpers/setup_request'; import { getDocumentTypeFilterForAggregatedTransactions, getProcessorEventForAggregatedTransactions, @@ -66,17 +62,17 @@ export async function getBuckets({ traceId: string; distributionMax: number; bucketSize: number; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; searchAggregatedTransactions: boolean; }) { - const { start, end, uiFiltersES, apmEventClient } = setup; + const { start, end, esFilter, apmEventClient } = setup; const commonFilters = [ { term: { [SERVICE_NAME]: serviceName } }, { term: { [TRANSACTION_TYPE]: transactionType } }, { term: { [TRANSACTION_NAME]: transactionName } }, { range: rangeFilter(start, end) }, - ...uiFiltersES, + ...esFilter, ]; async function getSamplesForDistributionBuckets() { diff --git a/x-pack/plugins/apm/server/lib/transactions/distribution/get_distribution_max.ts b/x-pack/plugins/apm/server/lib/transactions/distribution/get_distribution_max.ts index 24ca2a4a07b68..249b1c4fbb20a 100644 --- a/x-pack/plugins/apm/server/lib/transactions/distribution/get_distribution_max.ts +++ b/x-pack/plugins/apm/server/lib/transactions/distribution/get_distribution_max.ts @@ -9,11 +9,7 @@ import { TRANSACTION_NAME, TRANSACTION_TYPE, } from '../../../../common/elasticsearch_fieldnames'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; import { getProcessorEventForAggregatedTransactions, getTransactionDurationFieldForAggregatedTransactions, @@ -29,10 +25,10 @@ export async function getDistributionMax({ serviceName: string; transactionName: string; transactionType: string; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; searchAggregatedTransactions: boolean; }) { - const { start, end, uiFiltersES, apmEventClient } = setup; + const { start, end, esFilter, apmEventClient } = setup; const params = { apm: { @@ -59,7 +55,7 @@ export async function getDistributionMax({ }, }, }, - ...uiFiltersES, + ...esFilter, ], }, }, diff --git a/x-pack/plugins/apm/server/lib/transactions/distribution/index.ts b/x-pack/plugins/apm/server/lib/transactions/distribution/index.ts index b9ab36fb08d42..deafc37ee42e2 100644 --- a/x-pack/plugins/apm/server/lib/transactions/distribution/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/distribution/index.ts @@ -5,11 +5,7 @@ */ import { PromiseReturnType } from '../../../../../observability/typings/common'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; import { getBuckets } from './get_buckets'; import { getDistributionMax } from './get_distribution_max'; import { roundToNearestFiveOrTen } from '../../helpers/round_to_nearest_five_or_ten'; @@ -39,7 +35,7 @@ export async function getTransactionDistribution({ transactionType: string; transactionId: string; traceId: string; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; searchAggregatedTransactions: boolean; }) { const distributionMax = await getDistributionMax({ diff --git a/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts b/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts index 9aa1a8f4de87f..8958be0819613 100644 --- a/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/get_transaction/index.ts @@ -9,11 +9,7 @@ import { TRANSACTION_ID, } from '../../../../common/elasticsearch_fieldnames'; import { rangeFilter } from '../../../../common/utils/range_filter'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../helpers/setup_request'; import { ProcessorEvent } from '../../../../common/processor_event'; export async function getTransaction({ @@ -23,7 +19,7 @@ export async function getTransaction({ }: { transactionId: string; traceId: string; - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; }) { const { start, end, apmEventClient } = setup; diff --git a/x-pack/plugins/apm/server/lib/transactions/queries.test.ts b/x-pack/plugins/apm/server/lib/transactions/queries.test.ts index 87b8bc7c4ae90..eff9451c9e1cd 100644 --- a/x-pack/plugins/apm/server/lib/transactions/queries.test.ts +++ b/x-pack/plugins/apm/server/lib/transactions/queries.test.ts @@ -56,7 +56,6 @@ describe('transaction queries', () => { setup, searchAggregatedTransactions: false, logger: loggerMock.create(), - uiFilters: {}, }) ); expect(mock.params).toMatchSnapshot(); @@ -71,7 +70,6 @@ describe('transaction queries', () => { setup, searchAggregatedTransactions: false, logger: loggerMock.create(), - uiFilters: {}, }) ); expect(mock.params).toMatchSnapshot(); @@ -86,7 +84,6 @@ describe('transaction queries', () => { setup, searchAggregatedTransactions: false, logger: loggerMock.create(), - uiFilters: {}, }) ); diff --git a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/__snapshots__/queries.test.ts.snap index 5f38432719280..e7ca65eb740b6 100644 --- a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/__snapshots__/queries.test.ts.snap @@ -46,7 +46,7 @@ Object { }, Object { "term": Object { - "my.custom.ui.filter": "foo-bar", + "service.environment": "test", }, }, ], diff --git a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/get_local_filter_query.ts b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/get_local_filter_query.ts index 10f6e93c1cfc1..9fbdba679b667 100644 --- a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/get_local_filter_query.ts +++ b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/get_local_filter_query.ts @@ -8,7 +8,7 @@ import { omit } from 'lodash'; import { mergeProjection } from '../../../projections/util/merge_projection'; import { Projection } from '../../../projections/typings'; import { UIFilters } from '../../../../typings/ui_filters'; -import { getUiFiltersES } from '../../helpers/convert_ui_filters/get_ui_filters_es'; +import { getEsFilter } from '../../helpers/convert_ui_filters/get_es_filter'; import { localUIFilters } from './config'; import { LocalUIFilterName } from '../../../../common/ui_filter'; @@ -22,7 +22,7 @@ export const getLocalFilterQuery = ({ localUIFilterName: LocalUIFilterName; }) => { const field = localUIFilters[localUIFilterName]; - const filter = getUiFiltersES(omit(uiFilters, field.name)); + const filter = getEsFilter(omit(uiFilters, field.name)); const bucketCountAggregation = projection.body.aggs ? { diff --git a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/queries.test.ts b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/queries.test.ts index 22fa20e255f6e..f4e8aafc1bcf5 100644 --- a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/queries.test.ts +++ b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/queries.test.ts @@ -15,7 +15,7 @@ describe('local ui filter queries', () => { let mock: SearchParamsMock; beforeEach(() => { - jest.mock('../../helpers/convert_ui_filters/get_ui_filters_es', () => { + jest.mock('../../helpers/convert_ui_filters/get_es_filter', () => { return []; }); }); diff --git a/x-pack/plugins/apm/server/projections/errors.ts b/x-pack/plugins/apm/server/projections/errors.ts index 49a0e9f479d26..173dc94a0840c 100644 --- a/x-pack/plugins/apm/server/projections/errors.ts +++ b/x-pack/plugins/apm/server/projections/errors.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../server/lib/helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request'; import { SERVICE_NAME, ERROR_GROUP_ID, @@ -20,10 +16,10 @@ export function getErrorGroupsProjection({ setup, serviceName, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; serviceName: string; }) { - const { start, end, uiFiltersES } = setup; + const { start, end, esFilter } = setup; return { apm: { @@ -35,7 +31,7 @@ export function getErrorGroupsProjection({ filter: [ { term: { [SERVICE_NAME]: serviceName } }, { range: rangeFilter(start, end) }, - ...uiFiltersES, + ...esFilter, ], }, }, diff --git a/x-pack/plugins/apm/server/projections/metrics.ts b/x-pack/plugins/apm/server/projections/metrics.ts index eb80a6bc73248..c3b5db5be6af8 100644 --- a/x-pack/plugins/apm/server/projections/metrics.ts +++ b/x-pack/plugins/apm/server/projections/metrics.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../server/lib/helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request'; import { SERVICE_NAME, SERVICE_NODE_NAME, @@ -34,17 +30,17 @@ export function getMetricsProjection({ serviceName, serviceNodeName, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; serviceName: string; serviceNodeName?: string; }) { - const { start, end, uiFiltersES } = setup; + const { start, end, esFilter } = setup; const filter = [ { term: { [SERVICE_NAME]: serviceName } }, { range: rangeFilter(start, end) }, ...getServiceNodeNameFilters(serviceNodeName), - ...uiFiltersES, + ...esFilter, ]; return { diff --git a/x-pack/plugins/apm/server/projections/rum_page_load_transactions.ts b/x-pack/plugins/apm/server/projections/rum_page_load_transactions.ts index a8505337e8aec..96ee26c6e65f5 100644 --- a/x-pack/plugins/apm/server/projections/rum_page_load_transactions.ts +++ b/x-pack/plugins/apm/server/projections/rum_page_load_transactions.ts @@ -4,13 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request'; import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../server/lib/helpers/setup_request'; -import { - SPAN_TYPE, AGENT_NAME, TRANSACTION_TYPE, SERVICE_LANGUAGE_NAME, @@ -23,10 +18,10 @@ export function getRumPageLoadTransactionsProjection({ setup, urlQuery, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; urlQuery?: string; }) { - const { start, end, uiFiltersES } = setup; + const { start, end, esFilter } = setup; const bool = { filter: [ @@ -50,7 +45,7 @@ export function getRumPageLoadTransactionsProjection({ }, ] : []), - ...uiFiltersES, + ...esFilter, ], }; @@ -66,39 +61,12 @@ export function getRumPageLoadTransactionsProjection({ }; } -export function getRumLongTasksProjection({ - setup, -}: { - setup: Setup & SetupTimeRange & SetupUIFilters; -}) { - const { start, end, uiFiltersES } = setup; - - const bool = { - filter: [ - { range: rangeFilter(start, end) }, - { term: { [SPAN_TYPE]: 'longtask' } }, - ...uiFiltersES, - ], - }; - - return { - apm: { - events: [ProcessorEvent.span], - }, - body: { - query: { - bool, - }, - }, - }; -} - export function getRumErrorsProjection({ setup, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; }) { - const { start, end, uiFiltersES } = setup; + const { start, end, esFilter: esFilter } = setup; const bool = { filter: [ @@ -110,7 +78,7 @@ export function getRumErrorsProjection({ [SERVICE_LANGUAGE_NAME]: 'javascript', }, }, - ...uiFiltersES, + ...esFilter, ], }; diff --git a/x-pack/plugins/apm/server/projections/service_nodes.ts b/x-pack/plugins/apm/server/projections/service_nodes.ts index 87fe815a12d0d..ed8d4c7409eda 100644 --- a/x-pack/plugins/apm/server/projections/service_nodes.ts +++ b/x-pack/plugins/apm/server/projections/service_nodes.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../server/lib/helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request'; import { SERVICE_NODE_NAME } from '../../common/elasticsearch_fieldnames'; import { mergeProjection } from './util/merge_projection'; import { getMetricsProjection } from './metrics'; @@ -18,7 +14,7 @@ export function getServiceNodesProjection({ serviceName, serviceNodeName, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; serviceName: string; serviceNodeName?: string; }) { diff --git a/x-pack/plugins/apm/server/projections/services.ts b/x-pack/plugins/apm/server/projections/services.ts index ba61f72519a23..d912a95546515 100644 --- a/x-pack/plugins/apm/server/projections/services.ts +++ b/x-pack/plugins/apm/server/projections/services.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Setup, - SetupUIFilters, - SetupTimeRange, -} from '../../server/lib/helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request'; import { SERVICE_NAME } from '../../common/elasticsearch_fieldnames'; import { rangeFilter } from '../../common/utils/range_filter'; import { ProcessorEvent } from '../../common/processor_event'; @@ -18,10 +14,10 @@ export function getServicesProjection({ setup, searchAggregatedTransactions, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; searchAggregatedTransactions: boolean; }) { - const { start, end, uiFiltersES } = setup; + const { start, end, esFilter } = setup; return { apm: { @@ -37,7 +33,7 @@ export function getServicesProjection({ size: 0, query: { bool: { - filter: [{ range: rangeFilter(start, end) }, ...uiFiltersES], + filter: [{ range: rangeFilter(start, end) }, ...esFilter], }, }, aggs: { diff --git a/x-pack/plugins/apm/server/projections/transaction_groups.ts b/x-pack/plugins/apm/server/projections/transaction_groups.ts index 0cc3a7a35d214..2ce720eb12167 100644 --- a/x-pack/plugins/apm/server/projections/transaction_groups.ts +++ b/x-pack/plugins/apm/server/projections/transaction_groups.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { omit } from 'lodash'; -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../server/lib/helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request'; import { TRANSACTION_NAME, PARENT_ID, @@ -22,7 +18,7 @@ export function getTransactionGroupsProjection({ setup, options, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; options: Options; }) { const transactionsProjection = getTransactionsProjection({ diff --git a/x-pack/plugins/apm/server/projections/transactions.ts b/x-pack/plugins/apm/server/projections/transactions.ts index 8e9bb3bf321f6..548e77b5d2cd9 100644 --- a/x-pack/plugins/apm/server/projections/transactions.ts +++ b/x-pack/plugins/apm/server/projections/transactions.ts @@ -4,11 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - Setup, - SetupTimeRange, - SetupUIFilters, -} from '../../server/lib/helpers/setup_request'; +import { Setup, SetupTimeRange } from '../../server/lib/helpers/setup_request'; import { SERVICE_NAME, TRANSACTION_TYPE, @@ -27,13 +23,13 @@ export function getTransactionsProjection({ transactionType, searchAggregatedTransactions, }: { - setup: Setup & SetupTimeRange & SetupUIFilters; + setup: Setup & SetupTimeRange; serviceName?: string; transactionName?: string; transactionType?: string; searchAggregatedTransactions: boolean; }) { - const { start, end, uiFiltersES } = setup; + const { start, end, esFilter } = setup; const transactionNameFilter = transactionName ? [{ term: { [TRANSACTION_NAME]: transactionName } }] @@ -51,7 +47,7 @@ export function getTransactionsProjection({ ...transactionNameFilter, ...transactionTypeFilter, ...serviceNameFilter, - ...uiFiltersES, + ...esFilter, ...getDocumentTypeFilterForAggregatedTransactions( searchAggregatedTransactions ), diff --git a/x-pack/plugins/apm/server/routes/rum_client.ts b/x-pack/plugins/apm/server/routes/rum_client.ts index d86069a3ec27a..8dee8b759df26 100644 --- a/x-pack/plugins/apm/server/routes/rum_client.ts +++ b/x-pack/plugins/apm/server/routes/rum_client.ts @@ -89,8 +89,8 @@ export const rumPageLoadDistBreakdownRoute = createRoute(() => ({ return getPageLoadDistBreakdown({ setup, - minDuration: Number(minPercentile), - maxDuration: Number(maxPercentile), + minPercentile: Number(minPercentile), + maxPercentile: Number(maxPercentile), breakdown, urlQuery, }); @@ -177,12 +177,13 @@ export const rumLongTaskMetrics = createRoute(() => ({ const setup = await setupRequest(context, request); const { - query: { urlQuery }, + query: { urlQuery, percentile }, } = context.params; return getLongTaskMetrics({ setup, urlQuery, + percentile: percentile ? Number(percentile) : undefined, }); }, })); diff --git a/x-pack/plugins/apm/server/routes/service_map.ts b/x-pack/plugins/apm/server/routes/service_map.ts index 1996d4d4a262d..6e86ececd1bfe 100644 --- a/x-pack/plugins/apm/server/routes/service_map.ts +++ b/x-pack/plugins/apm/server/routes/service_map.ts @@ -17,7 +17,6 @@ import { createRoute } from './create_route'; import { rangeRt, uiFiltersRt } from './default_api_types'; import { notifyFeatureUsage } from '../feature'; import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; -import { getParsedUiFilters } from '../lib/helpers/convert_ui_filters/get_parsed_ui_filters'; export const serviceMapRoute = createRoute(() => ({ path: '/api/apm/service-map', @@ -77,24 +76,20 @@ export const serviceMapServiceNodeRoute = createRoute(() => ({ if (!isActivePlatinumLicense(context.licensing.license)) { throw Boom.forbidden(invalidLicenseMessage); } - const logger = context.logger; const setup = await setupRequest(context, request); const { - query: { uiFilters: uiFiltersJson }, path: { serviceName }, } = context.params; const searchAggregatedTransactions = await getSearchAggregatedTransactions( setup ); - const uiFilters = getParsedUiFilters({ uiFilters: uiFiltersJson, logger }); return getServiceMapServiceNodeInfo({ setup, serviceName, searchAggregatedTransactions, - uiFilters, }); }, })); diff --git a/x-pack/plugins/apm/server/routes/services.ts b/x-pack/plugins/apm/server/routes/services.ts index 4bb10f31ba6a1..538ba3926c792 100644 --- a/x-pack/plugins/apm/server/routes/services.ts +++ b/x-pack/plugins/apm/server/routes/services.ts @@ -17,7 +17,6 @@ import { uiFiltersRt, rangeRt } from './default_api_types'; import { getServiceAnnotations } from '../lib/services/annotations'; import { dateAsStringRt } from '../../common/runtime_types/date_as_string_rt'; import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; -import { getParsedUiFilters } from '../lib/helpers/convert_ui_filters/get_parsed_ui_filters'; export const servicesRoute = createRoute(() => ({ path: '/api/apm/services', @@ -25,22 +24,13 @@ export const servicesRoute = createRoute(() => ({ query: t.intersection([uiFiltersRt, rangeRt]), }, handler: async ({ context, request }) => { - const { environment } = getParsedUiFilters({ - uiFilters: context.params.query.uiFilters, - logger: context.logger, - }); - const setup = await setupRequest(context, request); const searchAggregatedTransactions = await getSearchAggregatedTransactions( setup ); - const services = await getServices({ - setup, - searchAggregatedTransactions, - mlAnomaliesEnvironment: environment, - }); + const services = await getServices({ setup, searchAggregatedTransactions }); return services; }, diff --git a/x-pack/plugins/apm/server/routes/transaction_groups.ts b/x-pack/plugins/apm/server/routes/transaction_groups.ts index dd1335fb2c2a1..18fc73b468cd4 100644 --- a/x-pack/plugins/apm/server/routes/transaction_groups.ts +++ b/x-pack/plugins/apm/server/routes/transaction_groups.ts @@ -5,6 +5,7 @@ */ import * as t from 'io-ts'; +import Boom from 'boom'; import { setupRequest } from '../lib/helpers/setup_request'; import { getTransactionCharts } from '../lib/transactions/charts'; import { getTransactionDistribution } from '../lib/transactions/distribution'; @@ -15,7 +16,6 @@ import { uiFiltersRt, rangeRt } from './default_api_types'; import { getTransactionSampleForGroup } from '../lib/transaction_groups/get_transaction_sample_for_group'; import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; import { getErrorRate } from '../lib/transaction_groups/get_error_rate'; -import { getParsedUiFilters } from '../lib/helpers/convert_ui_filters/get_parsed_ui_filters'; export const transactionGroupsRoute = createRoute(() => ({ path: '/api/apm/services/{serviceName}/transaction_groups', @@ -71,27 +71,28 @@ export const transactionGroupsChartsRoute = createRoute(() => ({ const setup = await setupRequest(context, request); const logger = context.logger; const { serviceName } = context.params.path; - const { - transactionType, - transactionName, - uiFilters: uiFiltersJson, - } = context.params.query; + const { transactionType, transactionName } = context.params.query; - const uiFilters = getParsedUiFilters({ uiFilters: uiFiltersJson, logger }); + if (!setup.uiFilters.environment) { + throw Boom.badRequest( + `environment is a required property of the ?uiFilters JSON for transaction_groups/charts.` + ); + } const searchAggregatedTransactions = await getSearchAggregatedTransactions( setup ); - return getTransactionCharts({ + const options = { serviceName, transactionType, transactionName, setup, searchAggregatedTransactions, logger, - uiFilters, - }); + }; + + return getTransactionCharts(options); }, })); diff --git a/x-pack/plugins/apm/server/routes/ui_filters.ts b/x-pack/plugins/apm/server/routes/ui_filters.ts index 936d460102dce..26fe0118c02ed 100644 --- a/x-pack/plugins/apm/server/routes/ui_filters.ts +++ b/x-pack/plugins/apm/server/routes/ui_filters.ts @@ -9,13 +9,12 @@ import { omit } from 'lodash'; import { setupRequest, Setup, - SetupUIFilters, SetupTimeRange, } from '../lib/helpers/setup_request'; import { getEnvironments } from '../lib/ui_filters/get_environments'; import { Projection } from '../projections/typings'; import { localUIFilterNames } from '../lib/ui_filters/local_ui_filters/config'; -import { getUiFiltersES } from '../lib/helpers/convert_ui_filters/get_ui_filters_es'; +import { getEsFilter } from '../lib/helpers/convert_ui_filters/get_es_filter'; import { getLocalUIFilters } from '../lib/ui_filters/local_ui_filters'; import { getServicesProjection } from '../projections/services'; import { getTransactionGroupsProjection } from '../projections/transaction_groups'; @@ -97,23 +96,23 @@ function createLocalFiltersRoute< }, handler: async ({ context, request }) => { const setup = await setupRequest(context, request); + const { uiFilters } = setup; const { query } = context.params; - const { uiFilters, filterNames } = query; - const parsedUiFilters = JSON.parse(uiFilters); + const { filterNames } = query; const projection = await getProjection({ query, context, setup: { ...setup, - uiFiltersES: getUiFiltersES(omit(parsedUiFilters, filterNames)), + esFilter: getEsFilter(omit(uiFilters, filterNames)), }, }); return getLocalUIFilters({ projection, setup, - uiFilters: parsedUiFilters, + uiFilters, localFilterNames: filterNames, }); }, @@ -271,6 +270,6 @@ type GetProjection< context, }: { query: t.TypeOf; - setup: Setup & SetupUIFilters & SetupTimeRange; + setup: Setup & SetupTimeRange; context: APMRequestHandlerContext; }) => Promise | TProjection; diff --git a/x-pack/plugins/apm/server/utils/test_helpers.tsx b/x-pack/plugins/apm/server/utils/test_helpers.tsx index 98c1436b2b9b8..18b990b35b5a5 100644 --- a/x-pack/plugins/apm/server/utils/test_helpers.tsx +++ b/x-pack/plugins/apm/server/utils/test_helpers.tsx @@ -9,6 +9,7 @@ import { ESSearchRequest, } from '../../typings/elasticsearch'; import { PromiseReturnType } from '../../typings/common'; +import { UIFilters } from '../../typings/ui_filters'; import { APMConfig } from '..'; interface Options { @@ -23,7 +24,8 @@ interface MockSetup { apmEventClient: any; internalClient: any; config: APMConfig; - uiFiltersES: ESFilter[]; + uiFilters: UIFilters; + esFilter: ESFilter[]; indices: { /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': string; @@ -78,7 +80,8 @@ export async function inspectSearchParams( }, } ) as APMConfig, - uiFiltersES: [{ term: { 'my.custom.ui.filter': 'foo-bar' } }], + uiFilters: { environment: 'test' }, + esFilter: [{ term: { 'service.environment': 'test' } }], indices: { /* eslint-disable @typescript-eslint/naming-convention */ 'apm_oss.sourcemapIndices': 'myIndex', diff --git a/x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx b/x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx index ebac34afa016b..57fb6d4fc33bb 100644 --- a/x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx +++ b/x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { get } from 'lodash'; import React from 'react'; import { EuiLink } from '@elastic/eui'; @@ -31,7 +31,7 @@ export const ConnectedLinkComponent = ({ } // Shorthand for pathname - const pathname = path || _.get(props.to, 'pathname') || location.pathname; + const pathname = path || get(props.to, 'pathname') || location.pathname; return ( { }); it('should use helper function to convert users yaml in tag to config object', async () => { - const convertedBlocks = lib.userConfigsToJson([ + const convertedBlocks = await lib.userConfigsToJson([ { id: 'foo', tag: 'basic', @@ -42,7 +42,7 @@ describe('Tags Client Domain Lib', () => { }); it('should use helper function to convert user config to json with undefined `other`', async () => { - const convertedTag = lib.userConfigsToJson([ + const convertedTag = await lib.userConfigsToJson([ { id: 'foo', tag: 'basic', @@ -61,7 +61,7 @@ describe('Tags Client Domain Lib', () => { }); it('should use helper function to convert users yaml in tag to config object, where empty other leads to no other fields saved', async () => { - const convertedTag = lib.userConfigsToJson([ + const convertedTag = await lib.userConfigsToJson([ { id: 'foo', tag: 'basic', @@ -83,7 +83,7 @@ describe('Tags Client Domain Lib', () => { }); it('should convert tokenized fields to JSON', async () => { - const convertedTag = lib.userConfigsToJson([ + const convertedTag = await lib.userConfigsToJson([ { id: 'foo', tag: 'basic', @@ -106,7 +106,7 @@ describe('Tags Client Domain Lib', () => { }); it('should use helper function to convert config object to users yaml', async () => { - const convertedTag = lib.jsonConfigToUserYaml([ + const convertedTag = await lib.jsonConfigToUserYaml([ { id: 'foo', tag: 'basic', @@ -127,7 +127,7 @@ describe('Tags Client Domain Lib', () => { }); it('should use helper function to convert config object to users yaml with empty `other`', async () => { - const convertedTag = lib.jsonConfigToUserYaml([ + const convertedTag = await lib.jsonConfigToUserYaml([ { id: 'foo', tag: 'basic', diff --git a/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts b/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts index 09c079ea129e6..d84bd21381c3e 100644 --- a/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts +++ b/x-pack/plugins/beats_management/public/lib/configuration_blocks.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import yaml from 'js-yaml'; import { set } from '@elastic/safer-lodash-set'; import { get, has, omit } from 'lodash'; import { ConfigBlockSchema, ConfigurationBlock } from '../../common/domain_types'; @@ -19,16 +18,17 @@ export class ConfigBlocksLib { ) {} public upsert = async (blocks: ConfigurationBlock[]) => { - return await this.adapter.upsert(this.userConfigsToJson(blocks)); + return await this.adapter.upsert(await this.userConfigsToJson(blocks)); }; public getForTags = async (tagIds: string[], page: number) => { const result = await this.adapter.getForTags(tagIds, page); - result.list = this.jsonConfigToUserYaml(result.list); + result.list = await this.jsonConfigToUserYaml(result.list); return result; }; - public jsonConfigToUserYaml(blocks: ConfigurationBlock[]): ConfigurationBlock[] { + public async jsonConfigToUserYaml(blocks: ConfigurationBlock[]): Promise { + const yaml = await import('js-yaml'); // configuration_blocks yaml, JS cant read YAML so we parse it into JS, // because beats flattens all fields, and we need more structure. // we take tagConfigs, grab the config that applies here, render what we can into @@ -73,7 +73,8 @@ export class ConfigBlocksLib { }); } - public userConfigsToJson(blocks: ConfigurationBlock[]): ConfigurationBlock[] { + public async userConfigsToJson(blocks: ConfigurationBlock[]): Promise { + const yaml = await import('js-yaml'); // configurations is the JS representation of the config yaml, // so here we take that JS and convert it into a YAML string. // we do so while also flattening "other" into the flat yaml beats expect diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.test.js b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.test.js index 71b6af6739408..1c75f5b7e0fbc 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.test.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.test.js @@ -12,16 +12,16 @@ import { markdown } from './markdown'; describe('markdown', () => { const fn = functionWrapper(markdown); - it('returns a render as markdown', () => { - const result = fn(null, { content: [''], font: fontStyle }); + it('returns a render as markdown', async () => { + const result = await fn(null, { content: [''], font: fontStyle }); expect(result).toHaveProperty('type', 'render'); expect(result).toHaveProperty('as', 'markdown'); }); describe('args', () => { describe('content', () => { - it('sets the content to all strings in expression concatenated', () => { - const result = fn(null, { + it('sets the content to all strings in expression concatenated', async () => { + const result = await fn(null, { content: ['# this ', 'is ', 'some ', 'markdown'], font: fontStyle, }); @@ -29,11 +29,11 @@ describe('markdown', () => { expect(result.value).toHaveProperty('content', '# this is some markdown'); }); - it('compiles and concatenates handlebars expressions using context', () => { + it('compiles and concatenates handlebars expressions using context', async () => { let expectedContent = 'Columns:'; testTable.columns.map((col) => (expectedContent += ` ${col.name}`)); - const result = fn(testTable, { + const result = await fn(testTable, { content: ['Columns:', '{{#each columns}} {{name}}{{/each}}'], }); @@ -42,8 +42,8 @@ describe('markdown', () => { }); describe('font', () => { - it('sets the font style for the markdown', () => { - const result = fn(null, { + it('sets the font style for the markdown', async () => { + const result = await fn(null, { content: ['some ', 'markdown'], font: fontStyle, }); @@ -55,8 +55,8 @@ describe('markdown', () => { // it("defaults to the expression '{font}'", () => {}); }); describe('openLinksInNewTab', () => { - it('sets the value of openLinksInNewTab to true ', () => { - const result = fn(null, { + it('sets the value of openLinksInNewTab to true ', async () => { + const result = await fn(null, { content: ['some ', 'markdown'], openLinksInNewTab: true, }); @@ -64,8 +64,8 @@ describe('markdown', () => { expect(result.value).toHaveProperty('openLinksInNewTab', true); }); - it('sets the value of openLinksInNewTab to false ', () => { - const result = fn(null, { + it('sets the value of openLinksInNewTab to false ', async () => { + const result = await fn(null, { content: ['some ', 'markdown'], openLinksInNewTab: false, }); @@ -73,8 +73,8 @@ describe('markdown', () => { expect(result.value).toHaveProperty('openLinksInNewTab', false); }); - it('defaults the value of openLinksInNewTab to false ', () => { - const result = fn(null, { + it('defaults the value of openLinksInNewTab to false ', async () => { + const result = await fn(null, { content: ['some ', 'markdown'], }); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts index 947106fd9397a..aa73eba456481 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/browser/markdown.ts @@ -10,8 +10,6 @@ import { Style, ExpressionFunctionDefinition, } from 'src/plugins/expressions/common'; -// @ts-expect-error untyped local -import { Handlebars } from '../../../common/lib/handlebars'; import { getFunctionHelp } from '../../../i18n'; type Context = Datatable | null; @@ -32,7 +30,7 @@ export function markdown(): ExpressionFunctionDefinition< 'markdown', Context, Arguments, - Render + Promise> > { const { help, args: argHelp } = getFunctionHelp().markdown; @@ -61,7 +59,9 @@ export function markdown(): ExpressionFunctionDefinition< default: false, }, }, - fn: (input, args) => { + fn: async (input, args) => { + // @ts-expect-error untyped local + const { Handlebars } = await import('../../../common/lib/handlebars'); const compileFunctions = args.content.map((str) => Handlebars.compile(String(str), { knownHelpersOnly: true }) ); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.tsx index 622e73ccf2223..29e823e0a373b 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/pie/index.tsx @@ -6,7 +6,6 @@ // This bit of hackiness is required because this isn't part of the main kibana bundle import 'jquery'; -import '../../lib/flot-charts'; import { debounce, includes } from 'lodash'; import { RendererStrings } from '../../../i18n'; @@ -22,7 +21,10 @@ export const pie: RendererFactory = () => ({ displayName: strings.getDisplayName(), help: strings.getHelpDescription(), reuseDomNode: false, - render(domNode, config, handlers) { + render: async (domNode, config, handlers) => { + // @ts-expect-error + await import('../../lib/flot-charts'); + if (!includes($.plot.plugins, piePlugin)) { $.plot.plugins.push(piePlugin); } diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.ts index 8c84f54f8746b..9d70ca418f491 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/plot/index.ts @@ -6,7 +6,6 @@ // This bit of hackiness is required because this isn't part of the main kibana bundle import 'jquery'; -import '../../lib/flot-charts'; import { debounce, includes } from 'lodash'; import { RendererStrings } from '../../../i18n'; @@ -18,7 +17,10 @@ import { text } from './plugins/text'; const { plot: strings } = RendererStrings; -const render: RendererSpec['render'] = (domNode, config, handlers) => { +const render: RendererSpec['render'] = async (domNode, config, handlers) => { + // @ts-expect-error + await import('../../lib/flot-charts'); + // TODO: OH NOES if (!includes($.plot.plugins, size)) { $.plot.plugins.push(size); 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/shareable_runtime/components/__tests__/app.test.tsx b/x-pack/plugins/canvas/shareable_runtime/components/__tests__/app.test.tsx index 2ec3cfde8bd68..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 @@ -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/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/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/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/infra/public/legacy_singletons.ts b/x-pack/plugins/global_search/common/constants.ts similarity index 58% rename from x-pack/plugins/infra/public/legacy_singletons.ts rename to x-pack/plugins/global_search/common/constants.ts index f57047f21c281..423cf5f8be5a8 100644 --- a/x-pack/plugins/infra/public/legacy_singletons.ts +++ b/x-pack/plugins/global_search/common/constants.ts @@ -3,12 +3,5 @@ * 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 }; +export const defaultMaxProviderResults = 40; diff --git a/x-pack/plugins/global_search/public/services/search_service.ts b/x-pack/plugins/global_search/public/services/search_service.ts index 68970b75ad975..62b347d925868 100644 --- a/x-pack/plugins/global_search/public/services/search_service.ts +++ b/x-pack/plugins/global_search/public/services/search_service.ts @@ -12,6 +12,7 @@ import { HttpStart } from 'src/core/public'; import { GlobalSearchProviderResult, GlobalSearchBatchedResults } from '../../common/types'; import { GlobalSearchFindError } from '../../common/errors'; import { takeInArray } from '../../common/operators'; +import { defaultMaxProviderResults } from '../../common/constants'; import { processProviderResult } from '../../common/process_result'; import { ILicenseChecker } from '../../common/license_checker'; import { GlobalSearchResultProvider } from '../types'; @@ -79,7 +80,6 @@ interface StartDeps { licenseChecker: ILicenseChecker; } -const defaultMaxProviderResults = 20; const mapToUndefined = () => undefined; /** @internal */ diff --git a/x-pack/plugins/global_search/server/services/search_service.ts b/x-pack/plugins/global_search/server/services/search_service.ts index d79f3781c6bec..1897a24196cf1 100644 --- a/x-pack/plugins/global_search/server/services/search_service.ts +++ b/x-pack/plugins/global_search/server/services/search_service.ts @@ -11,6 +11,7 @@ import { KibanaRequest, CoreStart, IBasePath } from 'src/core/server'; import { GlobalSearchProviderResult, GlobalSearchBatchedResults } from '../../common/types'; import { GlobalSearchFindError } from '../../common/errors'; import { takeInArray } from '../../common/operators'; +import { defaultMaxProviderResults } from '../../common/constants'; import { ILicenseChecker } from '../../common/license_checker'; import { processProviderResult } from '../../common/process_result'; @@ -80,7 +81,6 @@ interface StartDeps { licenseChecker: ILicenseChecker; } -const defaultMaxProviderResults = 20; const mapToUndefined = () => undefined; /** @internal */ 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..3c86c4e70e346 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 @@ -5,16 +5,19 @@ */ import React from 'react'; -import { wait } from '@testing-library/react'; -import { of } from 'rxjs'; +import { waitFor, act } from '@testing-library/react'; +import { ReactWrapper } from 'enzyme'; +import { of, BehaviorSubject } from 'rxjs'; +import { filter, map } from 'rxjs/operators'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; -import { - GlobalSearchBatchedResults, - GlobalSearchPluginStart, - GlobalSearchResult, -} from '../../../global_search/public'; +import { applicationServiceMock } from '../../../../../src/core/public/mocks'; +import { GlobalSearchBatchedResults, GlobalSearchResult } from '../../../global_search/public'; import { globalSearchPluginMock } from '../../../global_search/public/mocks'; -import { SearchBar } from '../components/search_bar'; +import { SearchBar } from './search_bar'; + +jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ + htmlIdGenerator: () => () => 'mockId', +})); type Result = { id: string; type: string } | string; @@ -37,26 +40,46 @@ const createBatch = (...results: Result[]): GlobalSearchBatchedResults => ({ results: results.map(createResult), }); -jest.mock('@elastic/eui/lib/services/accessibility/html_id_generator', () => ({ - htmlIdGenerator: () => () => 'mockId', -})); - const getSelectableProps: any = (component: any) => component.find('EuiSelectable').props(); const getSearchProps: any = (component: any) => component.find('EuiFieldSearch').props(); describe('SearchBar', () => { - let searchService: GlobalSearchPluginStart; - let findSpy: jest.SpyInstance; + let searchService: ReturnType; + let applications: ReturnType; + const basePathUrl = '/plugins/globalSearchBar/assets/'; + const darkMode = false; + + let component: ReactWrapper; beforeEach(() => { + applications = applicationServiceMock.createStartContract(); searchService = globalSearchPluginMock.createStartContract(); - findSpy = jest.spyOn(searchService, 'find'); jest.useFakeTimers(); }); + const triggerFocus = () => { + component.find('input[data-test-subj="header-search"]').simulate('focus'); + }; + + const update = () => { + act(() => { + jest.runAllTimers(); + }); + component.update(); + }; + + const simulateTypeChar = async (text: string) => { + await waitFor(() => + getSearchProps(component).onKeyUpCapture({ currentTarget: { value: text } }) + ); + }; + + const getDisplayedOptionsLabel = () => { + return getSelectableProps(component).options.map((option: any) => option.label); + }; + it('correctly filters and sorts results', async () => { - const navigate = jest.fn(); - findSpy + searchService.find .mockReturnValueOnce( of( createBatch('Discover', 'Canvas'), @@ -65,27 +88,41 @@ describe('SearchBar', () => { ) .mockReturnValueOnce(of(createBatch('Discover', { id: 'My Dashboard', type: 'test' }))); - const component = mountWithIntl( - + component = mountWithIntl( + ); - expect(findSpy).toHaveBeenCalledTimes(0); - component.find('input[data-test-subj="header-search"]').simulate('focus'); - jest.runAllTimers(); - component.update(); - expect(findSpy).toHaveBeenCalledTimes(1); - expect(findSpy).toHaveBeenCalledWith('', {}); + expect(searchService.find).toHaveBeenCalledTimes(0); + + triggerFocus(); + update(); + + expect(searchService.find).toHaveBeenCalledTimes(1); + expect(searchService.find).toHaveBeenCalledWith('', {}); expect(getSelectableProps(component).options).toMatchSnapshot(); - await wait(() => getSearchProps(component).onKeyUpCapture({ currentTarget: { value: 'd' } })); - jest.runAllTimers(); - component.update(); + + await simulateTypeChar('d'); + update(); + expect(getSelectableProps(component).options).toMatchSnapshot(); - expect(findSpy).toHaveBeenCalledTimes(2); - expect(findSpy).toHaveBeenCalledWith('d', {}); + expect(searchService.find).toHaveBeenCalledTimes(2); + expect(searchService.find).toHaveBeenCalledWith('d', {}); }); it('supports keyboard shortcuts', () => { - mountWithIntl(); + mountWithIntl( + + ); const searchEvent = new KeyboardEvent('keydown', { key: '/', @@ -96,4 +133,44 @@ describe('SearchBar', () => { expect(document.activeElement).toMatchSnapshot(); }); + + it('only display results from the last search', async () => { + const firstSearchTrigger = new BehaviorSubject(false); + const firstSearch = firstSearchTrigger.pipe( + filter((event) => event), + map(() => { + return createBatch('Discover', 'Canvas'); + }) + ); + const secondSearch = of(createBatch('Visualize', 'Map')); + + searchService.find.mockReturnValueOnce(firstSearch).mockReturnValueOnce(secondSearch); + + component = mountWithIntl( + + ); + + triggerFocus(); + update(); + + expect(searchService.find).toHaveBeenCalledTimes(1); + + await simulateTypeChar('d'); + update(); + + expect(getDisplayedOptionsLabel().length).toBe(2); + expect(getDisplayedOptionsLabel()).toEqual(expect.arrayContaining(['Visualize', 'Map'])); + + firstSearchTrigger.next(true); + + update(); + + expect(getDisplayedOptionsLabel().length).toBe(2); + expect(getDisplayedOptionsLabel()).toEqual(expect.arrayContaining(['Visualize', 'Map'])); + }); }); 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 0dde28db0436d..ea2271286883d 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,13 +12,15 @@ import { EuiSelectableTemplateSitewideOption, EuiText, EuiIcon, + EuiImage, EuiHeaderSectionItemButton, EuiSelectableMessage, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { Subscription } from 'rxjs'; import { ApplicationStart } from 'kibana/public'; -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useState, useRef } from 'react'; import useDebounce from 'react-use/lib/useDebounce'; import useEvent from 'react-use/lib/useEvent'; import useMountedState from 'react-use/lib/useMountedState'; @@ -27,6 +29,8 @@ import { GlobalSearchPluginStart, GlobalSearchResult } from '../../../global_sea interface Props { globalSearch: GlobalSearchPluginStart['find']; navigateToUrl: ApplicationStart['navigateToUrl']; + basePathUrl: string; + darkMode: boolean; } const clearField = (field: HTMLInputElement) => { @@ -42,48 +46,73 @@ 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) { +const sortByScore = (a: GlobalSearchResult, b: GlobalSearchResult): number => { + if (a.score < b.score) return 1; + if (a.score > b.score) return -1; + return 0; +}; + +const sortByTitle = (a: GlobalSearchResult, b: GlobalSearchResult): number => { + const titleA = a.title.toUpperCase(); // ignore upper and lowercase + const titleB = b.title.toUpperCase(); // ignore upper and lowercase + if (titleA < titleB) return -1; + if (titleA > titleB) return 1; + return 0; +}; + +const resultToOption = (result: GlobalSearchResult): EuiSelectableTemplateSitewideOption => { + const { id, title, url, icon, type, meta } = result; + const option: EuiSelectableTemplateSitewideOption = { + key: id, + label: title, + url, + }; + + if (icon) { + option.icon = { type: icon }; + } + + if (type === 'application') { + option.meta = [{ text: meta?.categoryLabel as string }]; + } else { + option.meta = [{ text: cleanMeta(type) }]; + } + + return option; +}; + +export function SearchBar({ globalSearch, navigateToUrl, basePathUrl, darkMode }: Props) { const isMounted = useMountedState(); const [searchValue, setSearchValue] = useState(''); const [searchRef, setSearchRef] = useState(null); + const searchSubscription = useRef(null); const [options, _setOptions] = useState([] as EuiSelectableTemplateSitewideOption[]); const isMac = navigator.platform.toLowerCase().indexOf('mac') >= 0; const setOptions = useCallback( (_options: GlobalSearchResult[]) => { - if (!isMounted()) return; - - _setOptions([ - ..._options.map(({ id, title, url, icon, type, meta }) => { - const option: EuiSelectableTemplateSitewideOption = { - key: id, - label: title, - url, - }; - - if (icon) option.icon = { type: icon }; - - if (type === 'application') option.meta = [{ text: meta?.categoryLabel as string }]; - else option.meta = [{ text: cleanMeta(type) }]; + if (!isMounted()) { + return; + } - return option; - }), - ]); + _setOptions(_options.map(resultToOption)); }, [isMounted, _setOptions] ); useDebounce( () => { + // cancel pending search if not completed yet + if (searchSubscription.current) { + searchSubscription.current.unsubscribe(); + searchSubscription.current = null; + } + let arr: GlobalSearchResult[] = []; - globalSearch(searchValue, {}).subscribe({ + searchSubscription.current = globalSearch(searchValue, {}).subscribe({ next: ({ results }) => { if (searchValue.length > 0) { - arr = [...results, ...arr].sort((a, b) => { - if (a.score < b.score) return 1; - if (a.score > b.score) return -1; - return 0; - }); + arr = [...results, ...arr].sort(sortByScore); setOptions(arr); return; } @@ -91,13 +120,7 @@ export function SearchBar({ globalSearch, navigateToUrl }: Props) { // if searchbar is empty, filter to only applications and sort alphabetically results = results.filter(({ type }: GlobalSearchResult) => type === 'application'); - arr = [...results, ...arr].sort((a, b) => { - const titleA = a.title.toUpperCase(); // ignore upper and lowercase - const titleB = b.title.toUpperCase(); // ignore upper and lowercase - if (titleA < titleB) return -1; - if (titleA > titleB) return 1; - return 0; - }); + arr = [...results, ...arr].sort(sortByTitle); setOptions(arr); }, @@ -134,6 +157,34 @@ export function SearchBar({ globalSearch, navigateToUrl }: Props) { } }; + const emptyMessage = ( + + + +

+ +

+
+

+ +

+
+ ); + useEvent('keydown', onKeyDown); return ( @@ -164,22 +215,8 @@ export function SearchBar({ globalSearch, navigateToUrl }: Props) { popoverProps={{ repositionOnScroll: true, }} - emptyMessage={ - -

- -

-

- -

-
- } + 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/global_search_providers/server/providers/saved_objects/provider.test.ts b/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.test.ts index 352191658ed0d..b556e2785b4b4 100644 --- a/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.test.ts +++ b/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.test.ts @@ -5,6 +5,7 @@ */ import { EMPTY } from 'rxjs'; +import { toArray } from 'rxjs/operators'; import { TestScheduler } from 'rxjs/testing'; import { SavedObjectsFindResponse, @@ -114,8 +115,8 @@ describe('savedObjectsResultProvider', () => { expect(provider.id).toBe('savedObjects'); }); - it('calls `savedObjectClient.find` with the correct parameters', () => { - provider.find('term', defaultOption, context); + it('calls `savedObjectClient.find` with the correct parameters', async () => { + await provider.find('term', defaultOption, context).toPromise(); expect(context.core.savedObjects.client.find).toHaveBeenCalledTimes(1); expect(context.core.savedObjects.client.find).toHaveBeenCalledWith({ @@ -128,6 +129,13 @@ describe('savedObjectsResultProvider', () => { }); }); + it('does not call `savedObjectClient.find` if `term` is empty', async () => { + const results = await provider.find('', defaultOption, context).pipe(toArray()).toPromise(); + + expect(context.core.savedObjects.client.find).not.toHaveBeenCalled(); + expect(results).toEqual([[]]); + }); + it('converts the saved objects to results', async () => { context.core.savedObjects.client.find.mockResolvedValue( createFindResponse([ diff --git a/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.ts b/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.ts index 1c79380fe17fd..3861858a53626 100644 --- a/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.ts +++ b/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { from, combineLatest } from 'rxjs'; +import { from, combineLatest, of } from 'rxjs'; import { map, takeUntil, first } from 'rxjs/operators'; import { GlobalSearchResultProvider } from '../../../../global_search/server'; import { mapToResults } from './map_object_to_result'; @@ -13,6 +13,10 @@ export const createSavedObjectsResultProvider = (): GlobalSearchResultProvider = return { id: 'savedObjects', find: (term, { aborted$, maxResults, preference }, { core }) => { + if (!term) { + return of([]); + } + const { capabilities, savedObjects: { client, typeRegistry }, 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/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/components/alerting/shared/criterion_preview_chart/criterion_preview_chart.tsx b/x-pack/plugins/infra/public/alerting/common/criterion_preview_chart/criterion_preview_chart.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/alerting/shared/criterion_preview_chart/criterion_preview_chart.tsx rename to x-pack/plugins/infra/public/alerting/common/criterion_preview_chart/criterion_preview_chart.tsx index 239afd93a7a1f..9003e13869e60 100644 --- a/x-pack/plugins/infra/public/components/alerting/shared/criterion_preview_chart/criterion_preview_chart.tsx +++ b/x-pack/plugins/infra/public/alerting/common/criterion_preview_chart/criterion_preview_chart.tsx @@ -11,8 +11,8 @@ 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'; +import { formatNumber } from '../../../../common/formatters/number'; +import { GetLogAlertsChartPreviewDataSuccessResponsePayload } from '../../../../common/http_api'; type Series = GetLogAlertsChartPreviewDataSuccessResponsePayload['data']['series']; 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/log_threshold/alert_dropdown.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/alert_dropdown.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx index 74634bbd5d290..b8eb73b99f45e 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/alert_dropdown.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_dropdown.tsx @@ -8,7 +8,7 @@ import React, { useState, useCallback, useMemo } from 'react'; import { EuiPopover, EuiButtonEmpty, EuiContextMenuItem, EuiContextMenuPanel } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { AlertFlyout } from './alert_flyout'; -import { useLinkProps } from '../../../../hooks/use_link_props'; +import { useLinkProps } from '../../../hooks/use_link_props'; export const AlertDropdown = () => { const [popoverOpen, setPopoverOpen] = useState(false); diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/alert_flyout.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_flyout.tsx similarity index 84% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/alert_flyout.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/alert_flyout.tsx index c6e16dcc9aaef..cd69fe02c5846 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/alert_flyout.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/alert_flyout.tsx @@ -6,10 +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/log_threshold/types'; +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/log_threshold/types'; interface Props { visible?: boolean; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/criteria.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx similarity index 98% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/criteria.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx index a607b5ebf9975..c35e7141efc9d 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/criteria.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criteria.tsx @@ -20,10 +20,10 @@ import { isRatioAlert, getNumerator, getDenominator, -} from '../../../../../../common/alerting/logs/log_threshold/types'; +} from '../../../../../common/alerting/logs/log_threshold/types'; +import { Errors, CriterionErrors } from '../../validation'; import { AlertsContext, ExpressionLike } from './editor'; import { CriterionPreview } from './criterion_preview_chart'; -import { Errors, CriterionErrors } from '../validation'; const DEFAULT_CRITERIA = { field: 'log.level', comparator: Comparator.EQ, value: 'error' }; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/criterion.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx similarity index 98% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/criterion.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx index 8ecd172c08d24..b2992ead3ea1b 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/criterion.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion.tsx @@ -21,12 +21,12 @@ 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'; +import { IErrorObject } from '../../../../../../triggers_actions_ui/public/types'; import { Comparator, Criterion as CriterionType, ComparatorToi18nMap, -} from '../../../../../../common/alerting/logs/log_threshold/types'; +} from '../../../../../common/alerting/logs/log_threshold/types'; const firstCriterionFieldPrefix = i18n.translate( 'xpack.infra.logs.alertFlyout.firstCriterionFieldPrefix', diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/criterion_preview_chart.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx similarity index 96% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/criterion_preview_chart.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx index 675900499e793..478d4b879a7e1 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/criterion_preview_chart.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/criterion_preview_chart.tsx @@ -31,21 +31,21 @@ import { getChartTheme, yAxisFormatter, NUM_BUCKETS, -} from '../../../shared/criterion_preview_chart/criterion_preview_chart'; +} 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'; +} from '../../../../../common/alerting/logs/log_threshold/types'; +import { Color, colorTransformer } from '../../../../../common/color_palette'; import { GetLogAlertsChartPreviewDataAlertParamsSubset, getLogAlertsChartPreviewDataAlertParamsSubsetRT, -} from '../../../../../../common/http_api/log_alerts/'; +} from '../../../../../common/http_api/log_alerts/'; import { AlertsContext } from './editor'; import { useChartPreviewData } from './hooks/use_chart_preview_data'; -import { decodeOrThrow } from '../../../../../../common/runtime_types'; +import { decodeOrThrow } from '../../../../../common/runtime_types'; const GROUP_LIMIT = 5; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/editor.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx similarity index 93% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/editor.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx index 0af96a7e06a2b..c5b0ed5844852 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/editor.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/editor.tsx @@ -8,25 +8,23 @@ 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, - // 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 { AlertsContextValue } from '../../../../../../../triggers_actions_ui/public/application/context/alerts_context'; + AlertsContextValue, +} from '../../../../../../triggers_actions_ui/public'; import { AlertParams, Comparator, ThresholdType, isRatioAlert, -} from '../../../../../../common/alerting/logs/log_threshold/types'; +} 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 { GroupByExpression } from '../../../shared/group_by_expression/group_by_expression'; -import { Errors } from '../validation'; +import { useSourceId } from '../../../../containers/source_id'; +import { LogSourceProvider, useLogSourceContext } from '../../../../containers/logs/log_source'; +import { Errors } from '../../validation'; export interface ExpressionCriteria { field?: string; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/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 90% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/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 index d43e291f900f2..d5ba730026b12 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/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 @@ -5,15 +5,15 @@ */ import { useState, useMemo } from 'react'; import { AlertsContext } from '../editor'; -import { useTrackedPromise } from '../../../../../../utils/use_tracked_promise'; +import { useTrackedPromise } from '../../../../../utils/use_tracked_promise'; import { GetLogAlertsChartPreviewDataSuccessResponsePayload, getLogAlertsChartPreviewDataSuccessResponsePayloadRT, getLogAlertsChartPreviewDataRequestPayloadRT, LOG_ALERTS_CHART_PREVIEW_DATA_PATH, -} from '../../../../../../../common/http_api'; -import { decodeOrThrow } from '../../../../../../../common/runtime_types'; -import { GetLogAlertsChartPreviewDataAlertParamsSubset } from '../../../../../../../common/http_api/log_alerts/'; +} from '../../../../../../common/http_api'; +import { decodeOrThrow } from '../../../../../../common/runtime_types'; +import { GetLogAlertsChartPreviewDataAlertParamsSubset } from '../../../../../../common/http_api/log_alerts/'; interface Options { sourceId: string; diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/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/log_threshold/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/components/alerting/logs/log_threshold/expression_editor/threshold.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/threshold.tsx similarity index 95% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/threshold.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/threshold.tsx index e2065ca25cb6f..da0c987bac85f 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/threshold.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/threshold.tsx @@ -18,12 +18,12 @@ import { EuiFormRow, } from '@elastic/eui'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { IErrorObject } from '../../../../../../../triggers_actions_ui/public/types'; +import { IErrorObject } from '../../../../../../triggers_actions_ui/public/types'; import { Comparator, ComparatorToi18nMap, AlertParams, -} from '../../../../../../common/alerting/logs/log_threshold/types'; +} from '../../../../../common/alerting/logs/log_threshold/types'; const thresholdPrefix = i18n.translate('xpack.infra.logs.alertFlyout.thresholdPrefix', { defaultMessage: 'is', diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/type_switcher.tsx b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/type_switcher.tsx similarity index 97% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/type_switcher.tsx rename to x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/type_switcher.tsx index 03c895dcd0f2d..5f5078f8aa6e1 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/expression_editor/type_switcher.tsx +++ b/x-pack/plugins/infra/public/alerting/log_threshold/components/expression_editor/type_switcher.tsx @@ -11,7 +11,7 @@ import { AlertParams, ThresholdType, isRatioAlert, -} from '../../../../../../common/alerting/logs/log_threshold/types'; +} from '../../../../../common/alerting/logs/log_threshold/types'; import { ExpressionLike } from './editor'; const typePrefix = i18n.translate('xpack.infra.logs.alertFlyout.thresholdTypePrefix', { 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/components/alerting/logs/log_threshold/log_threshold_alert_type.ts b/x-pack/plugins/infra/public/alerting/log_threshold/log_threshold_alert_type.ts similarity index 80% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/log_threshold_alert_type.ts rename to x-pack/plugins/infra/public/alerting/log_threshold/log_threshold_alert_type.ts index 15ff5844c1236..29a58fc95f2be 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/log_threshold_alert_type.ts +++ b/x-pack/plugins/infra/public/alerting/log_threshold/log_threshold_alert_type.ts @@ -5,9 +5,8 @@ */ 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/log_threshold/types'; +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 { @@ -17,7 +16,7 @@ export function getAlertType(): AlertTypeModel { defaultMessage: 'Log threshold', }), iconClass: 'bell', - alertParamsExpression: React.lazy(() => import('./expression_editor/editor')), + alertParamsExpression: React.lazy(() => import('./components/expression_editor/editor')), validate: validateExpression, defaultActionMessage: i18n.translate( 'xpack.infra.logs.alerting.threshold.defaultActionMessage', diff --git a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/validation.ts b/x-pack/plugins/infra/public/alerting/log_threshold/validation.ts similarity index 94% rename from x-pack/plugins/infra/public/components/alerting/logs/log_threshold/validation.ts rename to x-pack/plugins/infra/public/alerting/log_threshold/validation.ts index a7f773c08d2b3..6630b3d079141 100644 --- a/x-pack/plugins/infra/public/components/alerting/logs/log_threshold/validation.ts +++ b/x-pack/plugins/infra/public/alerting/log_threshold/validation.ts @@ -6,8 +6,7 @@ import { i18n } from '@kbn/i18n'; import { isNumber, isFinite } from 'lodash'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ValidationResult } from '../../../../../../triggers_actions_ui/public/types'; +import { ValidationResult } from '../../../../triggers_actions_ui/public'; import { AlertParams, Criteria, @@ -15,7 +14,7 @@ import { isRatioAlert, getNumerator, getDenominator, -} from '../../../../../common/alerting/logs/log_threshold/types'; +} from '../../../common/alerting/logs/log_threshold/types'; export interface CriterionErrors { [id: string]: { 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/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 973037af499e5..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/log_threshold/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 801dff9c4a17a..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) { @@ -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 428c002da6383..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]); 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 f33e3ea16b389..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,6 +5,7 @@ */ import { useMemo, useState, useCallback, useEffect, useReducer } from 'react'; +import { HttpHandler } from 'src/core/public'; import { INFA_ML_GET_METRICS_HOSTS_ANOMALIES_PATH, Metric, @@ -16,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; @@ -149,6 +150,7 @@ export const useMetricsHostsAnomaliesResults = ({ onGetMetricsHostsAnomaliesDatasetsError?: (error: Error) => void; filteredDatasets?: string[]; }) => { + const { services } = useKibanaContextForPlugin(); const initStateReducer = (stateDefaults: ReducerStateDefaults): ReducerState => { return { ...stateDefaults, @@ -177,15 +179,18 @@ export const useMetricsHostsAnomaliesResults = ({ paginationCursor, } = reducerState; return await callGetMetricHostsAnomaliesAPI( - sourceId, - queryStartTime, - queryEndTime, - metric, - 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 } }) => { @@ -288,15 +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, - metric: Metric, - 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({ 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 89e70c4c5c4c7..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, @@ -16,8 +17,8 @@ import { 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; @@ -149,6 +150,7 @@ export const useMetricsK8sAnomaliesResults = ({ onGetMetricsHostsAnomaliesDatasetsError?: (error: Error) => void; filteredDatasets?: string[]; }) => { + const { services } = useKibanaContextForPlugin(); const initStateReducer = (stateDefaults: ReducerStateDefaults): ReducerState => { return { ...stateDefaults, @@ -178,16 +180,19 @@ export const useMetricsK8sAnomaliesResults = ({ filteredDatasets: queryFilteredDatasets, } = reducerState; return await callGetMetricsK8sAnomaliesAPI( - sourceId, - queryStartTime, - queryEndTime, - metric, - 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 } }) => { @@ -290,16 +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, - metric: Metric, - 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({ diff --git a/x-pack/plugins/infra/public/plugin.ts b/x-pack/plugins/infra/public/plugin.ts index b409c32603ffc..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/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/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/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/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/openapi/spec_oas3.json b/x-pack/plugins/ingest_manager/common/openapi/spec_oas3.json index 28a88aa2be605..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", @@ -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/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/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/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/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 03060c5dcb20e..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 @@ -65,11 +65,11 @@ export const validatePackagePolicy = ( } 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; @@ -78,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/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 c840b487a3970..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 @@ -81,7 +81,7 @@ export const ManagedInstructions = React.memo(({ agentPolicies }) => { ), 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/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/server/constants/index.ts b/x-pack/plugins/ingest_manager/server/constants/index.ts index 3965e27da0542..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, 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/saved_objects/index.ts b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts index b3a8c7390176f..95433f896b9a3 100644 --- a/x-pack/plugins/ingest_manager/server/saved_objects/index.ts +++ b/x-pack/plugins/ingest_manager/server/saved_objects/index.ts @@ -33,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, @@ -111,7 +113,7 @@ const savedObjectTypes: { [key: string]: SavedObjectsType } = { }, }, migrations: { - '7.10.0': migrateAgentActionToV7100, + '7.10.0': migrateAgentActionToV7100(encryptedSavedObjects), }, }, [AGENT_EVENT_SAVED_OBJECT_TYPE]: { @@ -304,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 53af5ae42e410..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, @@ -94,17 +95,42 @@ export const migrateSettingsToV7100: SavedObjectMigrationFn< return settingsDoc; }; -export const migrateAgentActionToV7100: SavedObjectMigrationFn = ( - agentActionDoc -) => { - // @ts-expect-error - if (agentActionDoc.attributes.type === 'CONFIG_CHANGE') { - agentActionDoc.attributes.type = 'POLICY_CHANGE'; - if (agentActionDoc.attributes.data?.config) { - agentActionDoc.attributes.data.policy = agentActionDoc.attributes.data.config; - delete agentActionDoc.attributes.data.config; +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; + } } - } - - 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 29821a530098c..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( 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/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.ts b/x-pack/plugins/ingest_manager/server/services/agents/checkin/state_new_actions.ts index 51ccdc8eb1c7c..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 @@ -27,6 +27,7 @@ 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'; @@ -38,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: {}, @@ -166,19 +165,29 @@ export async function createAgentActionFromPolicyAction( 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, @@ -204,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/transform.test.ts b/x-pack/plugins/ingest_manager/server/services/epm/elasticsearch/transform/transform.test.ts index 7cb507d15679e..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 @@ -114,10 +114,10 @@ describe('test transform install', () => { ({ 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', @@ -131,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', @@ -146,7 +146,7 @@ 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/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', ], @@ -302,10 +302,10 @@ describe('test transform install', () => { ({ 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', @@ -404,10 +404,10 @@ describe('test transform install', () => { ({ 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', @@ -421,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', 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/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/install.ts b/x-pack/plugins/ingest_manager/server/services/epm/packages/install.ts index d501b05d96c1c..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 @@ -259,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 @@ -304,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 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/types/index.tsx b/x-pack/plugins/ingest_manager/server/types/index.tsx index b43d6355c479a..fc5ba1af196ad 100644 --- a/x-pack/plugins/ingest_manager/server/types/index.tsx +++ b/x-pack/plugins/ingest_manager/server/types/index.tsx @@ -45,7 +45,7 @@ export { InstallationStatus, PackageInfo, RegistryVarsEntry, - Dataset, + RegistryDataStream, RegistryElasticsearch, AssetReference, EsAssetReference, 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/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 index 5a88b47c0e894..09b9233197d2f 100644 --- a/x-pack/plugins/lens/public/async_services.ts +++ b/x-pack/plugins/lens/public/async_services.ts @@ -21,4 +21,5 @@ 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`] = ` - + + }; }, - 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 index c971540e165c1..410aaef9a5195 100644 --- a/x-pack/plugins/lens/public/drag_drop/drag_drop.scss +++ b/x-pack/plugins/lens/public/drag_drop/drag_drop.scss @@ -1,13 +1,54 @@ -.lnsDragDrop-isNotDroppable { - opacity: .5; +@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; } -// Fix specificity by chaining classes +// Drop area when there's an item being dragged +.lnsDragDrop-isDropTarget { + @include lnsDroppableActive; +} -.lnsDragDrop.lnsDragDrop-isDropTarget { - background-color: transparentize($euiColorSecondary, .9); +// Drop area while hovering with item +.lnsDragDrop-isActiveDropTarget { + @include lnsDroppableActiveHover; +} + +// Drop area that is not allowed for current item +.lnsDragDrop-isNotDroppable { + @include lnsDroppableNotAllowed; } -.lnsDragDrop.lnsDragDrop-isActiveDropTarget { - background-color: transparentize($euiColorSecondary, .75); +// 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 6941974a63cd3..b36415fee5b15 100644 --- a/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx +++ b/x-pack/plugins/lens/public/drag_drop/drag_drop.tsx @@ -41,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 @@ -60,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'; } /** @@ -98,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/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/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 index bad0563f16f1f..ac52190dc7b0d 100644 --- 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 @@ -20,7 +20,7 @@ .lnsFrameLayout__pageBody { @include euiScrollBar; min-width: $lnsPanelMinWidth + $euiSizeXL; - overflow: hidden; + 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 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/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 index 7f7385f029ed4..33b9b2fe1dbf0 100644 --- 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 @@ -1,3 +1,5 @@ +@import '../../../mixins'; + .lnsWorkspacePanelWrapper { @include euiScrollBar; overflow: hidden; @@ -7,6 +9,7 @@ display: flex; flex-direction: column; position: relative; // For positioning the dnd overlay + min-height: $euiSizeXXL * 10; .lnsWorkspacePanelWrapper__pageContentHeader { @include euiTitle('xs'); @@ -25,7 +28,7 @@ display: flex; align-items: stretch; justify-content: stretch; - overflow: hidden; + overflow: auto; > * { flex: 1 1 100%; @@ -41,6 +44,7 @@ // 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 { @@ -60,28 +64,25 @@ display: flex; justify-content: center; align-items: center; - transition: background-color $euiAnimSpeedNormal ease-in-out; + transition: background-color $euiAnimSpeedFast ease-in-out; .lnsDragDrop-isDropTarget & { - background-color: transparentize($euiColorSecondary, .9); + @include lnsDroppable; + @include lnsDroppableActive; p { - transition: filter $euiAnimSpeedNormal ease-in-out; + transition: filter $euiAnimSpeedFast ease-in-out; filter: blur(5px); } } .lnsDragDrop-isActiveDropTarget & { - background-color: transparentize($euiColorSecondary, .75); + @include lnsDroppableActiveHover; .lnsDropIllustration__hand { - animation: pulseArrowContinuous 1.5s ease-in-out 0s infinite normal forwards; + animation: lnsWorkspacePanel__illustrationPulseContinuous 1.5s ease-in-out 0s infinite normal forwards; } } - - &.lnsWorkspacePanel__emptyContent-onTop p { - display: none; - } } .lnsWorkspacePanelWrapper__toolbar { @@ -106,10 +107,10 @@ } .lnsDropIllustration__hand { - animation: pulseArrow 5s ease-in-out 0s infinite normal forwards; + animation: lnsWorkspacePanel__illustrationPulseArrow 5s ease-in-out 0s infinite normal forwards; } -@keyframes pulseArrow { +@keyframes lnsWorkspacePanel__illustrationPulseArrow { 0% { transform: translateY(0%); } 65% { transform: translateY(0%); } 72% { transform: translateY(10%); } @@ -118,7 +119,7 @@ 95% { transform: translateY(0); } } -@keyframes pulseArrowContinuous { +@keyframes lnsWorkspacePanel__illustrationPulseContinuous { 0% { transform: translateY(10%); } 25% { transform: translateY(15%); } 50% { transform: translateY(10%); } 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 8892217f5d51d..e6d7f78f5ad07 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/service.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/service.tsx @@ -25,10 +25,8 @@ import { Document } from '../persistence/saved_object_store'; 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 { @@ -77,6 +75,8 @@ export class EditorFrameService { collectAsyncDefinitions(this.visualizations), ]); + const { persistedStateToExpression } = await import('../async_services'); + return await persistedStateToExpression(resolvedDatasources, resolvedVisualizations, doc); } @@ -133,7 +133,7 @@ export class EditorFrameService { const firstDatasourceId = Object.keys(resolvedDatasources)[0]; const firstVisualizationId = Object.keys(resolvedVisualizations)[0]; - const { EditorFrame } = await import('../async_services'); + const { EditorFrame, getActiveDatasourceIdFromDoc } = await import('../async_services'); render( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss index 155b954e9cf17..df73789eadedf 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss @@ -12,7 +12,7 @@ .lnsInnerIndexPatternDataPanel__fieldItems { // Quick fix for making sure the shadow and focus rings are visible outside the accordion bounds - padding: $euiSizeXS $euiSizeXS 0; + padding: $euiSizeXS; } .lnsInnerIndexPatternDataPanel__textField { 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 bd99bd16a63a8..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'; @@ -132,6 +132,15 @@ export function DimensionEditor(props: DimensionEditorProps) { }; }); + const selectedColumnSourceField = + selectedColumn && 'sourceField' in selectedColumn ? selectedColumn.sourceField : undefined; + + const currentFieldIsInvalid = useMemo( + () => + fieldIsInvalid(selectedColumnSourceField, selectedColumn?.operationType, currentIndexPattern), + [selectedColumnSourceField, selectedColumn?.operationType, currentIndexPattern] + ); + const sideNavItems: EuiListGroupItemProps[] = operationsWithCompatibility.map( ({ operationType, compatibleWithCurrentField }) => { const isActive = Boolean( @@ -248,7 +257,7 @@ export function DimensionEditor(props: DimensionEditorProps) {
{i18n.translate('xpack.lens.indexPattern.functionsLabel', { - defaultMessage: 'Choose a function', + defaultMessage: 'Select a function', })} @@ -268,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 270f9d9f67063..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(); 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 index d74c332dd42e5..1b55d9623e223 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.scss @@ -1,25 +1,25 @@ -.lnsFieldItem--missing { - .lnsFieldItem__info { - background: lightOrDarkTheme(transparentize($euiColorMediumShade, .9), $euiColorEmptyShade); - color: $euiColorDarkShade; - } -} - -.lnsFieldItem__info { +.lnsFieldItem { .lnsFieldItem__infoIcon { visibility: hidden; + opacity: 0; } - &:hover, - &:focus { + &: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; 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 7377d15bca6d7..2fbe23f9085f2 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx @@ -33,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, @@ -102,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; @@ -200,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} /> @@ -527,7 +514,7 @@ function FieldItemPopoverContents(props: State & FieldItemProps) {
- + {Math.round((otherCount / props.sampledValues!) * 100)}% 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/index.tsx similarity index 87% rename from x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx rename to x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx index c147029bbd3c7..85deb2bac25ca 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx @@ -6,24 +6,13 @@ 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; - }>; - } ->; +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', { @@ -182,30 +171,19 @@ export const termsOperation: OperationDefinition - | React.MouseEvent - ) => + onChange={(value) => { setState( updateColumnParam({ state, layerId, currentColumn, paramName: 'size', - value: Number((e.target as HTMLInputElement).value), + value, }) - ) - } - aria-label={i18n.translate('xpack.lens.indexPattern.terms.size', { - defaultMessage: 'Number of values', - })} + ); + }} /> { 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/expression.test.tsx b/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx index 0c92cdb2c31fc..77a8ce64b21a2 100644 --- a/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/metric_visualization/expression.test.tsx @@ -32,10 +32,21 @@ function sampleArgs() { accessor: 'a', layerId: 'l1', title: 'My fanci metric chart', + description: 'Fancy chart description', + metricTitle: 'My fanci metric chart', mode: 'full', }; - return { data, args }; + const noAttributesArgs: MetricConfig = { + accessor: 'a', + layerId: 'l1', + title: '', + description: '', + metricTitle: 'My fanci metric chart', + mode: 'full', + }; + + return { data, args, noAttributesArgs }; } describe('metric_expression', () => { @@ -53,7 +64,7 @@ describe('metric_expression', () => { }); describe('MetricChart component', () => { - test('it renders the title and value', () => { + test('it renders the all attributes when passed (title, description, metricTitle, value)', () => { const { data, args } = sampleArgs(); expect( @@ -61,6 +72,7 @@ describe('metric_expression', () => { ).toMatchInlineSnapshot(` @@ -90,21 +102,66 @@ describe('metric_expression', () => { `); }); - test('it does not render title in reduced mode', () => { - const { data, args } = sampleArgs(); + 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(` +
+ ); } @@ -119,14 +131,18 @@ export function MetricChart({ } return ( - +
{value}
{mode === 'full' && (
- {title} + {metricTitle}
)}
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 index aa3de93013e66..80c7a174b3264 100644 --- a/x-pack/plugins/lens/public/metric_visualization/visualization.test.ts +++ b/x-pack/plugins/lens/public/metric_visualization/visualization.test.ts @@ -171,11 +171,17 @@ describe('metric_visualization', () => { "accessor": Array [ "a", ], + "description": Array [ + "", + ], + "metricTitle": Array [ + "shazm", + ], "mode": Array [ "full", ], "title": Array [ - "shazm", + "", ], }, "function": "lens_metric_chart", diff --git a/x-pack/plugins/lens/public/metric_visualization/visualization.tsx b/x-pack/plugins/lens/public/metric_visualization/visualization.tsx index 72c07bed1acb2..77d189ce53d01 100644 --- a/x-pack/plugins/lens/public/metric_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/metric_visualization/visualization.tsx @@ -14,7 +14,7 @@ import { State } from './types'; const toExpression = ( state: State, datasourceLayers: Record, - mode: 'reduced' | 'full' = 'full' + attributes?: { mode?: 'reduced' | 'full'; title?: string; description?: string } ): Ast | null => { if (!state.accessor) { return null; @@ -30,9 +30,11 @@ const toExpression = ( type: 'function', function: 'lens_metric_chart', arguments: { - title: [(operation && operation.label) || ''], + title: [attributes?.title || ''], + description: [attributes?.description || ''], + metricTitle: [(operation && operation.label) || ''], accessor: [state.accessor], - mode: [mode], + mode: [attributes?.mode || 'full'], }, }, ], @@ -104,7 +106,7 @@ export const metricVisualization: Visualization = { toExpression, toPreviewExpression: (state, datasourceLayers) => - toExpression(state, datasourceLayers, 'reduced'), + toExpression(state, datasourceLayers, { mode: 'reduced' }), setDimension({ prevState, columnId }) { return { ...prevState, accessor: columnId }; diff --git a/x-pack/plugins/lens/public/pie_visualization/expression.tsx b/x-pack/plugins/lens/public/pie_visualization/expression.tsx index 89d93ab79233f..d93145f29aa89 100644 --- a/x-pack/plugins/lens/public/pie_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/expression.tsx @@ -37,6 +37,14 @@ export const pie: ExpressionFunctionDefinition< defaultMessage: 'Pie renderer', }), args: { + title: { + types: ['string'], + help: 'The chart title.', + }, + description: { + types: ['string'], + help: '', + }, groups: { types: ['string'], multi: true, 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 ( - +