From f0f75fc289d8335f2f4ff799f44a6b764488f989 Mon Sep 17 00:00:00 2001 From: Rudolf Meijering Date: Tue, 8 Oct 2019 16:41:13 +0200 Subject: [PATCH 01/19] SavedObjectAttribute allow array of primitives (#47317) --- .../core/public/kibana-plugin-public.md | 5 +++-- ...na-plugin-public.savedobject.attributes.md | 2 +- .../kibana-plugin-public.savedobject.md | 2 +- ...bana-plugin-public.savedobjectattribute.md | 3 ++- ...ana-plugin-public.savedobjectattributes.md | 2 +- ...lugin-public.savedobjectattributesingle.md | 13 +++++++++++++ .../core/server/kibana-plugin-server.md | 5 +++-- ...na-plugin-server.savedobject.attributes.md | 2 +- .../kibana-plugin-server.savedobject.md | 2 +- ...bana-plugin-server.savedobjectattribute.md | 3 ++- ...ana-plugin-server.savedobjectattributes.md | 2 +- ...lugin-server.savedobjectattributesingle.md | 13 +++++++++++++ src/core/public/index.ts | 1 + src/core/public/public.api.md | 9 ++++++--- src/core/public/saved_objects/index.ts | 1 + src/core/server/index.ts | 1 + src/core/server/saved_objects/types.ts | 19 +++++++++++++------ src/core/server/server.api.md | 9 ++++++--- 18 files changed, 70 insertions(+), 24 deletions(-) create mode 100644 docs/development/core/public/kibana-plugin-public.savedobjectattributesingle.md create mode 100644 docs/development/core/server/kibana-plugin-server.savedobjectattributesingle.md diff --git a/docs/development/core/public/kibana-plugin-public.md b/docs/development/core/public/kibana-plugin-public.md index 7531cf9a06333..3c7943ba29388 100644 --- a/docs/development/core/public/kibana-plugin-public.md +++ b/docs/development/core/public/kibana-plugin-public.md @@ -70,7 +70,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [Plugin](./kibana-plugin-public.plugin.md) | The interface that should be returned by a PluginInitializer. | | [PluginInitializerContext](./kibana-plugin-public.plugininitializercontext.md) | The available core services passed to a PluginInitializer | | [SavedObject](./kibana-plugin-public.savedobject.md) | | -| [SavedObjectAttributes](./kibana-plugin-public.savedobjectattributes.md) | The data for a Saved Object is stored in the attributes key as either an object or an array of objects. | +| [SavedObjectAttributes](./kibana-plugin-public.savedobjectattributes.md) | The data for a Saved Object is stored as an object in the attributes property. | | [SavedObjectReference](./kibana-plugin-public.savedobjectreference.md) | A reference to another saved object. | | [SavedObjectsBaseOptions](./kibana-plugin-public.savedobjectsbaseoptions.md) | | | [SavedObjectsBatchResponse](./kibana-plugin-public.savedobjectsbatchresponse.md) | | @@ -104,7 +104,8 @@ The plugin integrates with the core system via lifecycle events: `setup` | [PluginInitializer](./kibana-plugin-public.plugininitializer.md) | The plugin export at the root of a plugin's public directory should conform to this interface. | | [PluginOpaqueId](./kibana-plugin-public.pluginopaqueid.md) | | | [RecursiveReadonly](./kibana-plugin-public.recursivereadonly.md) | | -| [SavedObjectAttribute](./kibana-plugin-public.savedobjectattribute.md) | | +| [SavedObjectAttribute](./kibana-plugin-public.savedobjectattribute.md) | Type definition for a Saved Object attribute value | +| [SavedObjectAttributeSingle](./kibana-plugin-public.savedobjectattributesingle.md) | Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-public.savedobjectattribute.md) | | [SavedObjectsClientContract](./kibana-plugin-public.savedobjectsclientcontract.md) | SavedObjectsClientContract as implemented by the [SavedObjectsClient](./kibana-plugin-public.savedobjectsclient.md) | | [ToastInput](./kibana-plugin-public.toastinput.md) | | | [UiSettingsClientContract](./kibana-plugin-public.uisettingsclientcontract.md) | [UiSettingsClient](./kibana-plugin-public.uisettingsclient.md) | diff --git a/docs/development/core/public/kibana-plugin-public.savedobject.attributes.md b/docs/development/core/public/kibana-plugin-public.savedobject.attributes.md index f9d39c15fcff4..0ec57d679920c 100644 --- a/docs/development/core/public/kibana-plugin-public.savedobject.attributes.md +++ b/docs/development/core/public/kibana-plugin-public.savedobject.attributes.md @@ -4,7 +4,7 @@ ## SavedObject.attributes property -The data for a Saved Object is stored in the `attributes` key as either an object or an array of objects. +The data for a Saved Object is stored as an object in the `attributes` property. Signature: diff --git a/docs/development/core/public/kibana-plugin-public.savedobject.md b/docs/development/core/public/kibana-plugin-public.savedobject.md index 9bf0149f0854e..00260c62dd934 100644 --- a/docs/development/core/public/kibana-plugin-public.savedobject.md +++ b/docs/development/core/public/kibana-plugin-public.savedobject.md @@ -15,7 +15,7 @@ export interface SavedObject | Property | Type | Description | | --- | --- | --- | -| [attributes](./kibana-plugin-public.savedobject.attributes.md) | T | The data for a Saved Object is stored in the attributes key as either an object or an array of objects. | +| [attributes](./kibana-plugin-public.savedobject.attributes.md) | T | The data for a Saved Object is stored as an object in the attributes property. | | [error](./kibana-plugin-public.savedobject.error.md) | {
message: string;
statusCode: number;
} | | | [id](./kibana-plugin-public.savedobject.id.md) | string | The ID of this Saved Object, guaranteed to be unique for all objects of the same type | | [migrationVersion](./kibana-plugin-public.savedobject.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. | diff --git a/docs/development/core/public/kibana-plugin-public.savedobjectattribute.md b/docs/development/core/public/kibana-plugin-public.savedobjectattribute.md index f8d51390863eb..5ce6a60f76c79 100644 --- a/docs/development/core/public/kibana-plugin-public.savedobjectattribute.md +++ b/docs/development/core/public/kibana-plugin-public.savedobjectattribute.md @@ -4,9 +4,10 @@ ## SavedObjectAttribute type +Type definition for a Saved Object attribute value Signature: ```typescript -export declare type SavedObjectAttribute = string | number | boolean | null | undefined | SavedObjectAttributes | SavedObjectAttributes[]; +export declare type SavedObjectAttribute = SavedObjectAttributeSingle | SavedObjectAttributeSingle[]; ``` diff --git a/docs/development/core/public/kibana-plugin-public.savedobjectattributes.md b/docs/development/core/public/kibana-plugin-public.savedobjectattributes.md index 4a9e096cc25b7..39c02216f4827 100644 --- a/docs/development/core/public/kibana-plugin-public.savedobjectattributes.md +++ b/docs/development/core/public/kibana-plugin-public.savedobjectattributes.md @@ -4,7 +4,7 @@ ## SavedObjectAttributes interface -The data for a Saved Object is stored in the `attributes` key as either an object or an array of objects. +The data for a Saved Object is stored as an object in the `attributes` property. Signature: diff --git a/docs/development/core/public/kibana-plugin-public.savedobjectattributesingle.md b/docs/development/core/public/kibana-plugin-public.savedobjectattributesingle.md new file mode 100644 index 0000000000000..3f2d70baa64e6 --- /dev/null +++ b/docs/development/core/public/kibana-plugin-public.savedobjectattributesingle.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [SavedObjectAttributeSingle](./kibana-plugin-public.savedobjectattributesingle.md) + +## SavedObjectAttributeSingle type + +Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-public.savedobjectattribute.md) + +Signature: + +```typescript +export declare type SavedObjectAttributeSingle = string | number | boolean | null | undefined | SavedObjectAttributes; +``` diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md index 1247c52a5704b..02bbd028ac419 100644 --- a/docs/development/core/server/kibana-plugin-server.md +++ b/docs/development/core/server/kibana-plugin-server.md @@ -76,7 +76,7 @@ The plugin integrates with the core system via lifecycle events: `setup` | [RouteConfig](./kibana-plugin-server.routeconfig.md) | Route specific configuration. | | [RouteConfigOptions](./kibana-plugin-server.routeconfigoptions.md) | Additional route options. | | [SavedObject](./kibana-plugin-server.savedobject.md) | | -| [SavedObjectAttributes](./kibana-plugin-server.savedobjectattributes.md) | The data for a Saved Object is stored in the attributes key as either an object or an array of objects. | +| [SavedObjectAttributes](./kibana-plugin-server.savedobjectattributes.md) | The data for a Saved Object is stored as an object in the attributes property. | | [SavedObjectReference](./kibana-plugin-server.savedobjectreference.md) | A reference to another saved object. | | [SavedObjectsBaseOptions](./kibana-plugin-server.savedobjectsbaseoptions.md) | | | [SavedObjectsBulkCreateObject](./kibana-plugin-server.savedobjectsbulkcreateobject.md) | | @@ -152,7 +152,8 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ResponseErrorAttributes](./kibana-plugin-server.responseerrorattributes.md) | Additional data to provide error details. | | [ResponseHeaders](./kibana-plugin-server.responseheaders.md) | Http response headers to set. | | [RouteMethod](./kibana-plugin-server.routemethod.md) | The set of common HTTP methods supported by Kibana routing. | -| [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) | | +| [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) | Type definition for a Saved Object attribute value | +| [SavedObjectAttributeSingle](./kibana-plugin-server.savedobjectattributesingle.md) | Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) | | [SavedObjectsClientContract](./kibana-plugin-server.savedobjectsclientcontract.md) | Saved Objects is Kibana's data persisentence mechanism allowing plugins to use Elasticsearch for storing plugin state.\#\# SavedObjectsClient errorsSince the SavedObjectsClient has its hands in everything we are a little paranoid about the way we present errors back to to application code. Ideally, all errors will be either:1. Caused by bad implementation (ie. undefined is not a function) and as such unpredictable 2. An error that has been classified and decorated appropriately by the decorators in [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md)Type 1 errors are inevitable, but since all expected/handle-able errors should be Type 2 the isXYZError() helpers exposed at SavedObjectsErrorHelpers should be used to understand and manage error responses from the SavedObjectsClient.Type 2 errors are decorated versions of the source error, so if the elasticsearch client threw an error it will be decorated based on its type. That means that rather than looking for error.body.error.type or doing substring checks on error.body.error.reason, just use the helpers to understand the meaning of the error:\`\`\`js if (SavedObjectsErrorHelpers.isNotFoundError(error)) { // handle 404 }if (SavedObjectsErrorHelpers.isNotAuthorizedError(error)) { // 401 handling should be automatic, but in case you wanted to know }// always rethrow the error unless you handle it throw error; \`\`\`\#\#\# 404s from missing indexFrom the perspective of application code and APIs the SavedObjectsClient is a black box that persists objects. One of the internal details that users have no control over is that we use an elasticsearch index for persistance and that index might be missing.At the time of writing we are in the process of transitioning away from the operating assumption that the SavedObjects index is always available. Part of this transition is handling errors resulting from an index missing. These used to trigger a 500 error in most cases, and in others cause 404s with different error messages.From my (Spencer) perspective, a 404 from the SavedObjectsApi is a 404; The object the request/call was targeting could not be found. This is why \#14141 takes special care to ensure that 404 errors are generic and don't distinguish between index missing or document missing.\#\#\# 503s from missing indexUnlike all other methods, create requests are supposed to succeed even when the Kibana index does not exist because it will be automatically created by elasticsearch. When that is not the case it is because Elasticsearch's action.auto_create_index setting prevents it from being created automatically so we throw a special 503 with the intention of informing the user that their Elasticsearch settings need to be updated.See [SavedObjectsErrorHelpers](./kibana-plugin-server.savedobjectserrorhelpers.md) | | [SavedObjectsClientWrapperFactory](./kibana-plugin-server.savedobjectsclientwrapperfactory.md) | Describes the factory used to create instances of Saved Objects Client Wrappers. | diff --git a/docs/development/core/server/kibana-plugin-server.savedobject.attributes.md b/docs/development/core/server/kibana-plugin-server.savedobject.attributes.md index c3d521aa7bc2c..7049ca65e96d3 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobject.attributes.md +++ b/docs/development/core/server/kibana-plugin-server.savedobject.attributes.md @@ -4,7 +4,7 @@ ## SavedObject.attributes property -The data for a Saved Object is stored in the `attributes` key as either an object or an array of objects. +The data for a Saved Object is stored as an object in the `attributes` property. Signature: diff --git a/docs/development/core/server/kibana-plugin-server.savedobject.md b/docs/development/core/server/kibana-plugin-server.savedobject.md index 1514980588746..c7099cdce7ecd 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobject.md +++ b/docs/development/core/server/kibana-plugin-server.savedobject.md @@ -15,7 +15,7 @@ export interface SavedObject | Property | Type | Description | | --- | --- | --- | -| [attributes](./kibana-plugin-server.savedobject.attributes.md) | T | The data for a Saved Object is stored in the attributes key as either an object or an array of objects. | +| [attributes](./kibana-plugin-server.savedobject.attributes.md) | T | The data for a Saved Object is stored as an object in the attributes property. | | [error](./kibana-plugin-server.savedobject.error.md) | {
message: string;
statusCode: number;
} | | | [id](./kibana-plugin-server.savedobject.id.md) | string | The ID of this Saved Object, guaranteed to be unique for all objects of the same type | | [migrationVersion](./kibana-plugin-server.savedobject.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. | diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectattribute.md b/docs/development/core/server/kibana-plugin-server.savedobjectattribute.md index 6a6c7c4d36bc6..6696d9c6ce96d 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectattribute.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectattribute.md @@ -4,9 +4,10 @@ ## SavedObjectAttribute type +Type definition for a Saved Object attribute value Signature: ```typescript -export declare type SavedObjectAttribute = string | number | boolean | null | undefined | SavedObjectAttributes | SavedObjectAttributes[]; +export declare type SavedObjectAttribute = SavedObjectAttributeSingle | SavedObjectAttributeSingle[]; ``` diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectattributes.md b/docs/development/core/server/kibana-plugin-server.savedobjectattributes.md index 7ff1247e89f2d..6d24eb02b4eaf 100644 --- a/docs/development/core/server/kibana-plugin-server.savedobjectattributes.md +++ b/docs/development/core/server/kibana-plugin-server.savedobjectattributes.md @@ -4,7 +4,7 @@ ## SavedObjectAttributes interface -The data for a Saved Object is stored in the `attributes` key as either an object or an array of objects. +The data for a Saved Object is stored as an object in the `attributes` property. Signature: diff --git a/docs/development/core/server/kibana-plugin-server.savedobjectattributesingle.md b/docs/development/core/server/kibana-plugin-server.savedobjectattributesingle.md new file mode 100644 index 0000000000000..b2ddb59ddb252 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-server.savedobjectattributesingle.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [SavedObjectAttributeSingle](./kibana-plugin-server.savedobjectattributesingle.md) + +## SavedObjectAttributeSingle type + +Don't use this type, it's simply a helper type for [SavedObjectAttribute](./kibana-plugin-server.savedobjectattribute.md) + +Signature: + +```typescript +export declare type SavedObjectAttributeSingle = string | number | boolean | null | undefined | SavedObjectAttributes; +``` diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 9640f6f510c45..91f65a14986e9 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -91,6 +91,7 @@ export { SavedObject, SavedObjectAttribute, SavedObjectAttributes, + SavedObjectAttributeSingle, SavedObjectReference, SavedObjectsBaseOptions, SavedObjectsFindOptions, diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 0156cbaebb949..51a993ee5a5bb 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -716,15 +716,18 @@ export interface SavedObject { version?: string; } -// @public (undocumented) -export type SavedObjectAttribute = string | number | boolean | null | undefined | SavedObjectAttributes | SavedObjectAttributes[]; +// @public +export type SavedObjectAttribute = SavedObjectAttributeSingle | SavedObjectAttributeSingle[]; // @public export interface SavedObjectAttributes { // (undocumented) - [key: string]: SavedObjectAttribute | SavedObjectAttribute[]; + [key: string]: SavedObjectAttribute; } +// @public +export type SavedObjectAttributeSingle = string | number | boolean | null | undefined | SavedObjectAttributes; + // @public export interface SavedObjectReference { // (undocumented) diff --git a/src/core/public/saved_objects/index.ts b/src/core/public/saved_objects/index.ts index f82112c7a65bd..9452ece0ce823 100644 --- a/src/core/public/saved_objects/index.ts +++ b/src/core/public/saved_objects/index.ts @@ -33,6 +33,7 @@ export { SavedObject, SavedObjectAttribute, SavedObjectAttributes, + SavedObjectAttributeSingle, SavedObjectReference, SavedObjectsBaseOptions, SavedObjectsFindOptions, diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 3cc420b766439..027c82e419b5c 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -169,6 +169,7 @@ export { SavedObject, SavedObjectAttribute, SavedObjectAttributes, + SavedObjectAttributeSingle, SavedObjectReference, SavedObjectsBaseOptions, SavedObjectsClientContract, diff --git a/src/core/server/saved_objects/types.ts b/src/core/server/saved_objects/types.ts index e7e7a4c64392a..281ffe1ecc875 100644 --- a/src/core/server/saved_objects/types.ts +++ b/src/core/server/saved_objects/types.ts @@ -43,26 +43,33 @@ export interface SavedObjectsMigrationVersion { } /** + * Don't use this type, it's simply a helper type for {@link SavedObjectAttribute} * * @public */ -export type SavedObjectAttribute = +export type SavedObjectAttributeSingle = | string | number | boolean | null | undefined - | SavedObjectAttributes - | SavedObjectAttributes[]; + | SavedObjectAttributes; /** - * The data for a Saved Object is stored in the `attributes` key as either an - * object or an array of objects. + * Type definition for a Saved Object attribute value + * + * @public + */ +export type SavedObjectAttribute = SavedObjectAttributeSingle | SavedObjectAttributeSingle[]; + +/** + * The data for a Saved Object is stored as an object in the `attributes` + * property. * * @public */ export interface SavedObjectAttributes { - [key: string]: SavedObjectAttribute | SavedObjectAttribute[]; + [key: string]: SavedObjectAttribute; } /** diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 2de72cf1a35f6..01e6b63ee433a 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -1104,15 +1104,18 @@ export interface SavedObject { version?: string; } -// @public (undocumented) -export type SavedObjectAttribute = string | number | boolean | null | undefined | SavedObjectAttributes | SavedObjectAttributes[]; +// @public +export type SavedObjectAttribute = SavedObjectAttributeSingle | SavedObjectAttributeSingle[]; // @public export interface SavedObjectAttributes { // (undocumented) - [key: string]: SavedObjectAttribute | SavedObjectAttribute[]; + [key: string]: SavedObjectAttribute; } +// @public +export type SavedObjectAttributeSingle = string | number | boolean | null | undefined | SavedObjectAttributes; + // @public export interface SavedObjectReference { // (undocumented) From f440c03f44b1b814f06830336ee322e6d9ad5c52 Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Tue, 8 Oct 2019 09:45:35 -0500 Subject: [PATCH 02/19] [APM] Add docs about running in VSCode to README (#47536) --- x-pack/legacy/plugins/apm/readme.md | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/x-pack/legacy/plugins/apm/readme.md b/x-pack/legacy/plugins/apm/readme.md index 679169aaf89db..90974cbe69588 100644 --- a/x-pack/legacy/plugins/apm/readme.md +++ b/x-pack/legacy/plugins/apm/readme.md @@ -64,3 +64,57 @@ yarn prettier "./x-pack/legacy/plugins/apm/**/*.{tsx,ts,js}" --write ``` yarn eslint ./x-pack/legacy/plugins/apm --fix ``` + +### Visual Studio Code + +When using [Visual Studio Code](https://code.visualstudio.com/) with APM it's best to set up a [multi-root workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces) and add the `x-pack/legacy/plugins/apm` directory, the `x-pack` directory, and the root of the Kibana repository to the workspace. This makes it so you can navigate and search within APM and use the wider workspace roots when you need to widen your search. + +#### Using the Jest extension + +The [vscode-jest extension](https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest) is a good way to run your Jest tests inside the editor. + +Some of the benefits of using the extension over just running it in a terminal are: + +• It shows the pass/fail of a test inline in the test file +• It shows the error message in the test file if it fails +• You don’t have to have the terminal process running +• It can automatically update your snapshots when they change +• Coverage mapping + +The extension doesn't really work well if you're trying to use it on all of Kibana or all of X-Pack, but it works well if you configure it to run only on the files in APM. + +If you have a workspace configured as described above you should have: + +```json +"jest.disabledWorkspaceFolders": ["kibana", "x-pack"] +``` + +in your Workspace settings, and: + +```json +"jest.pathToJest": "node scripts/jest.js --testPathPattern=legacy/plugins/apm", +"jest.rootPath": "../../.." +``` + +in the settings for the APM folder. + +#### Jest debugging + +To make the [VSCode debugger](https://vscode.readthedocs.io/en/latest/editor/debugging/) work with Jest (you can set breakpoints in the code and tests and use the VSCode debugger) you'll need the [Node Debug extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.node-debug2) installed and can set up a launch configuration like: + +```json +{ + "type": "node", + "name": "APM Jest", + "request": "launch", + "args": ["--runInBand", "--testPathPattern=legacy/plugins/apm"], + "cwd": "${workspaceFolder}/../../..", + "console": "internalConsole", + "internalConsoleOptions": "openOnSessionStart", + "disableOptimisticBPs": true, + "program": "${workspaceFolder}/../../../scripts/jest.js", + "runtimeVersion": "10.15.2" +} +``` + +(you'll want `runtimeVersion` to match what's in the Kibana root .nvmrc. Depending on your setup, you might be able to remove this line.) From 726a84f28cca3b1e37ab257edac17622fcacf1ea Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Tue, 8 Oct 2019 09:54:11 -0500 Subject: [PATCH 03/19] [APM] Experimental Service Map front end (#46497) Add service map tabs on the main APM screen and for individual services. This is not yet hooked up to work with back-end data, so it always shows the same hard-coded graph. This is experimental, so you must have x-pack.apm.serviceMapEnabled: true in your Kibana config for it to show up. Also add "PSF" to the list of allowed licenses since a new dependency added uses this license (it's on the [green list](https://github.com/elastic/open-source/blob/master/elastic-product-policy.md#green-list).) Fixes #44890 Fixes #44853 --- packages/kbn-pm/dist/index.js | 862 ++++++++++-------- renovate.json5 | 8 + src/dev/license_checker/config.ts | 1 + x-pack/legacy/plugins/apm/index.ts | 6 +- .../apm/public/components/app/Home/index.tsx | 19 +- .../app/Main/route_config/index.tsx | 24 + .../app/Main/route_config/route_names.tsx | 2 + .../app/ServiceDetails/ServiceDetailTabs.tsx | 21 +- .../components/app/ServiceMap/Controls.tsx | 108 +++ .../components/app/ServiceMap/Cytoscape.tsx | 93 ++ .../app/ServiceMap/FullscreenPanel.tsx | 57 ++ .../app/ServiceMap/cytoscapeOptions.ts | 92 ++ .../public/components/app/ServiceMap/icons.ts | 39 + .../app/ServiceMap/icons/database.svg | 3 + .../components/app/ServiceMap/icons/globe.svg | 3 + .../components/app/ServiceMap/index.tsx | 64 ++ .../shared/Links/apm/ServiceMapLink.tsx | 26 + .../context/UrlParamsContext/helpers.ts | 6 +- .../plugins/apm/server/lib/services/map.ts | 88 ++ .../apm/server/routes/create_apm_api.ts | 5 +- .../plugins/apm/server/routes/services.ts | 16 + .../plugins/apm/typings/cytoscape-dagre.d.ts | 7 + x-pack/package.json | 3 + yarn.lock | 118 ++- 24 files changed, 1246 insertions(+), 425 deletions(-) create mode 100644 x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Controls.tsx create mode 100644 x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Cytoscape.tsx create mode 100644 x-pack/legacy/plugins/apm/public/components/app/ServiceMap/FullscreenPanel.tsx create mode 100644 x-pack/legacy/plugins/apm/public/components/app/ServiceMap/cytoscapeOptions.ts create mode 100644 x-pack/legacy/plugins/apm/public/components/app/ServiceMap/icons.ts create mode 100644 x-pack/legacy/plugins/apm/public/components/app/ServiceMap/icons/database.svg create mode 100644 x-pack/legacy/plugins/apm/public/components/app/ServiceMap/icons/globe.svg create mode 100644 x-pack/legacy/plugins/apm/public/components/app/ServiceMap/index.tsx create mode 100644 x-pack/legacy/plugins/apm/public/components/shared/Links/apm/ServiceMapLink.tsx create mode 100644 x-pack/legacy/plugins/apm/server/lib/services/map.ts create mode 100644 x-pack/legacy/plugins/apm/typings/cytoscape-dagre.d.ts diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 5d2f5c786f2c2..f52c194cfee6a 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -38648,7 +38648,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(405); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); -/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(611); +/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(613); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); /* @@ -38828,8 +38828,8 @@ const EventEmitter = __webpack_require__(46); const path = __webpack_require__(16); const arrify = __webpack_require__(407); const globby = __webpack_require__(408); -const cpFile = __webpack_require__(601); -const CpyError = __webpack_require__(609); +const cpFile = __webpack_require__(603); +const CpyError = __webpack_require__(611); const preprocessSrcPath = (srcPath, options) => options.cwd ? path.resolve(options.cwd, srcPath) : srcPath; @@ -38958,8 +38958,8 @@ const fs = __webpack_require__(23); const arrayUnion = __webpack_require__(170); const glob = __webpack_require__(37); const fastGlob = __webpack_require__(409); -const dirGlob = __webpack_require__(594); -const gitignore = __webpack_require__(597); +const dirGlob = __webpack_require__(596); +const gitignore = __webpack_require__(599); const DEFAULT_FILTER = () => false; @@ -39128,11 +39128,11 @@ module.exports.generateTasks = pkg.generateTasks; Object.defineProperty(exports, "__esModule", { value: true }); var optionsManager = __webpack_require__(411); var taskManager = __webpack_require__(412); -var reader_async_1 = __webpack_require__(564); -var reader_stream_1 = __webpack_require__(588); -var reader_sync_1 = __webpack_require__(589); -var arrayUtils = __webpack_require__(591); -var streamUtils = __webpack_require__(592); +var reader_async_1 = __webpack_require__(566); +var reader_stream_1 = __webpack_require__(590); +var reader_sync_1 = __webpack_require__(591); +var arrayUtils = __webpack_require__(593); +var streamUtils = __webpack_require__(594); /** * Synchronous API. */ @@ -39790,17 +39790,17 @@ module.exports = function isGlob(str, options) { var util = __webpack_require__(29); var braces = __webpack_require__(420); -var toRegex = __webpack_require__(522); -var extend = __webpack_require__(530); +var toRegex = __webpack_require__(524); +var extend = __webpack_require__(532); /** * Local dependencies */ -var compilers = __webpack_require__(533); -var parsers = __webpack_require__(560); -var cache = __webpack_require__(561); -var utils = __webpack_require__(562); +var compilers = __webpack_require__(535); +var parsers = __webpack_require__(562); +var cache = __webpack_require__(563); +var utils = __webpack_require__(564); var MAX_LENGTH = 1024 * 64; /** @@ -46382,9 +46382,9 @@ module.exports = Braces; var Base = __webpack_require__(461); var define = __webpack_require__(422); -var Compiler = __webpack_require__(490); -var Parser = __webpack_require__(519); -var utils = __webpack_require__(499); +var Compiler = __webpack_require__(491); +var Parser = __webpack_require__(521); +var utils = __webpack_require__(501); var regexCache = {}; var cache = {}; @@ -46566,9 +46566,9 @@ var define = __webpack_require__(462); var CacheBase = __webpack_require__(463); var Emitter = __webpack_require__(464); var isObject = __webpack_require__(440); -var merge = __webpack_require__(481); -var pascal = __webpack_require__(484); -var cu = __webpack_require__(485); +var merge = __webpack_require__(482); +var pascal = __webpack_require__(485); +var cu = __webpack_require__(486); /** * Optionally define a custom `cache` namespace to use. @@ -47049,7 +47049,7 @@ var union = __webpack_require__(469); var del = __webpack_require__(473); var get = __webpack_require__(471); var has = __webpack_require__(478); -var set = __webpack_require__(472); +var set = __webpack_require__(481); /** * Create a `Cache` constructor that when instantiated will @@ -47775,52 +47775,60 @@ function toString(val) { -var split = __webpack_require__(436); +var toPath = __webpack_require__(468); var extend = __webpack_require__(430); var isPlainObject = __webpack_require__(439); var isObject = __webpack_require__(431); -module.exports = function(obj, prop, val) { +module.exports = function(obj, path, val) { if (!isObject(obj)) { return obj; } - if (Array.isArray(prop)) { - prop = [].concat.apply([], prop).join('.'); + if (Array.isArray(path)) { + path = toPath(path); } - if (typeof prop !== 'string') { + if (typeof path !== 'string') { return obj; } - var keys = split(prop, {sep: '.', brackets: true}).filter(isValidKey); - var len = keys.length; - var idx = -1; - var current = obj; + var segs = path.split('.'); + var len = segs.length, i = -1; + var res = obj; + var last; - while (++idx < len) { - var key = keys[idx]; - if (idx !== len - 1) { - if (!isObject(current[key])) { - current[key] = {}; - } - current = current[key]; - continue; + while (++i < len) { + var key = segs[i]; + + while (key[key.length - 1] === '\\') { + key = key.slice(0, -1) + '.' + segs[++i]; } - if (isPlainObject(current[key]) && isPlainObject(val)) { - current[key] = extend({}, current[key], val); - } else { - current[key] = val; + if (i === len - 1) { + last = key; + break; + } + + if (!isObject(obj[key])) { + obj[key] = {}; } + obj = obj[key]; } - return obj; + if (obj.hasOwnProperty(last) && isObject(obj[last])) { + if (isPlainObject(val)) { + extend(obj[last], val); + } else { + obj[last] = val; + } + + } else { + obj[last] = val; + } + return res; }; -function isValidKey(key) { - return key !== '__proto__' && key !== 'constructor' && key !== 'prototype'; -} /***/ }), @@ -48183,10 +48191,68 @@ module.exports = function kindOf(val) { /***/ (function(module, exports, __webpack_require__) { "use strict"; +/*! + * set-value + * + * Copyright (c) 2014-2015, 2017, Jon Schlinkert. + * Released under the MIT License. + */ + -var isExtendable = __webpack_require__(482); -var forIn = __webpack_require__(483); +var split = __webpack_require__(436); +var extend = __webpack_require__(430); +var isPlainObject = __webpack_require__(439); +var isObject = __webpack_require__(431); + +module.exports = function(obj, prop, val) { + if (!isObject(obj)) { + return obj; + } + + if (Array.isArray(prop)) { + prop = [].concat.apply([], prop).join('.'); + } + + if (typeof prop !== 'string') { + return obj; + } + + var keys = split(prop, {sep: '.', brackets: true}); + var len = keys.length; + var idx = -1; + var current = obj; + + while (++idx < len) { + var key = keys[idx]; + if (idx !== len - 1) { + if (!isObject(current[key])) { + current[key] = {}; + } + current = current[key]; + continue; + } + + if (isPlainObject(current[key]) && isPlainObject(val)) { + current[key] = extend({}, current[key], val); + } else { + current[key] = val; + } + } + + return obj; +}; + + +/***/ }), +/* 482 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var isExtendable = __webpack_require__(483); +var forIn = __webpack_require__(484); function mixinDeep(target, objects) { var len = arguments.length, i = 0; @@ -48250,7 +48316,7 @@ module.exports = mixinDeep; /***/ }), -/* 482 */ +/* 483 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48271,7 +48337,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 483 */ +/* 484 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48294,7 +48360,7 @@ module.exports = function forIn(obj, fn, thisArg) { /***/ }), -/* 484 */ +/* 485 */ /***/ (function(module, exports) { /*! @@ -48321,14 +48387,14 @@ module.exports = pascalcase; /***/ }), -/* 485 */ +/* 486 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(29); -var utils = __webpack_require__(486); +var utils = __webpack_require__(487); /** * Expose class utils @@ -48693,7 +48759,7 @@ cu.bubble = function(Parent, events) { /***/ }), -/* 486 */ +/* 487 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48710,7 +48776,7 @@ var utils = {}; utils.union = __webpack_require__(470); utils.define = __webpack_require__(422); utils.isObj = __webpack_require__(440); -utils.staticExtend = __webpack_require__(487); +utils.staticExtend = __webpack_require__(488); /** @@ -48721,7 +48787,7 @@ module.exports = utils; /***/ }), -/* 487 */ +/* 488 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48734,7 +48800,7 @@ module.exports = utils; -var copy = __webpack_require__(488); +var copy = __webpack_require__(489); var define = __webpack_require__(422); var util = __webpack_require__(29); @@ -48818,14 +48884,14 @@ module.exports = extend; /***/ }), -/* 488 */ +/* 489 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var typeOf = __webpack_require__(445); -var copyDescriptor = __webpack_require__(489); +var copyDescriptor = __webpack_require__(490); var define = __webpack_require__(422); /** @@ -48999,7 +49065,7 @@ module.exports.has = has; /***/ }), -/* 489 */ +/* 490 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49087,16 +49153,16 @@ function isObject(val) { /***/ }), -/* 490 */ +/* 491 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(491); +var use = __webpack_require__(492); var define = __webpack_require__(422); -var debug = __webpack_require__(492)('snapdragon:compiler'); -var utils = __webpack_require__(499); +var debug = __webpack_require__(494)('snapdragon:compiler'); +var utils = __webpack_require__(501); /** * Create a new `Compiler` with the given `options`. @@ -49250,7 +49316,7 @@ Compiler.prototype = { // source map support if (opts.sourcemap) { - var sourcemaps = __webpack_require__(518); + var sourcemaps = __webpack_require__(520); sourcemaps(this); this.mapVisit(this.ast.nodes); this.applySourceMaps(); @@ -49271,28 +49337,33 @@ module.exports = Compiler; /***/ }), -/* 491 */ +/* 492 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /*! * use * - * Copyright (c) 2015-2017, Jon Schlinkert. + * Copyright (c) 2015, 2017, Jon Schlinkert. * Released under the MIT License. */ -module.exports = function base(app, options) { - if (!isObject(app) && typeof app !== 'function') { - throw new TypeError('expected an object or function'); +var utils = __webpack_require__(493); + +module.exports = function base(app, opts) { + if (!utils.isObject(app) && typeof app !== 'function') { + throw new TypeError('use: expect `app` be an object or function'); } - var opts = isObject(options) ? options : {}; - var prop = typeof opts.prop === 'string' ? opts.prop : 'fns'; + if (!utils.isObject(opts)) { + opts = {}; + } + + var prop = utils.isString(opts.prop) ? opts.prop : 'fns'; if (!Array.isArray(app[prop])) { - define(app, prop, []); + utils.define(app, prop, []); } /** @@ -49325,7 +49396,7 @@ module.exports = function base(app, options) { * @api public */ - define(app, 'use', use); + utils.define(app, 'use', use); /** * Run all plugins on `fns`. Any plugin that returns a function @@ -49341,17 +49412,9 @@ module.exports = function base(app, options) { * @api public */ - define(app, 'run', function(val) { - if (!isObject(val)) return; - - if (!val.use || !val.run) { - define(val, prop, val[prop] || []); - define(val, 'use', use); - } - - if (!val[prop] || val[prop].indexOf(base) === -1) { - val.use(base); - } + utils.define(app, 'run', function(val) { + if (!utils.isObject(val)) return; + decorate(val); var self = this || app; var fns = self[prop]; @@ -49369,71 +49432,70 @@ module.exports = function base(app, options) { * `fns` array to be called by the `run` method. */ - function use(type, fn, options) { - var offset = 1; - - if (typeof type === 'string' || Array.isArray(type)) { - fn = wrap(type, fn); - offset++; - } else { - options = fn; - fn = type; - } - + function use(fn, options) { if (typeof fn !== 'function') { - throw new TypeError('expected a function'); + throw new TypeError('.use expects `fn` be a function'); } var self = this || app; - var fns = self[prop]; - - var args = [].slice.call(arguments, offset); - args.unshift(self); - - if (typeof opts.hook === 'function') { - opts.hook.apply(self, args); + if (typeof opts.fn === 'function') { + opts.fn.call(self, self, options); } - var val = fn.apply(self, args); - if (typeof val === 'function' && fns.indexOf(val) === -1) { - fns.push(val); + var plugin = fn.call(self, self); + if (typeof plugin === 'function') { + var fns = self[prop]; + fns.push(plugin); } return self; } /** - * Wrap a named plugin function so that it's only called on objects of the - * given `type` - * - * @param {String} `type` - * @param {Function} `fn` Plugin function - * @return {Function} + * Ensure the `.use` method exists on `val` */ - function wrap(type, fn) { - return function plugin() { - return this.type === type ? fn.apply(this, arguments) : plugin; - }; + function decorate(val) { + if (!val.use || !val.run) { + base(val); + } } return app; }; -function isObject(val) { - return val && typeof val === 'object' && !Array.isArray(val); -} -function define(obj, key, val) { - Object.defineProperty(obj, key, { - configurable: true, - writable: true, - value: val - }); -} +/***/ }), +/* 493 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var utils = {}; + + + +/** + * Lazily required module dependencies + */ + +utils.define = __webpack_require__(422); +utils.isObject = __webpack_require__(440); + + +utils.isString = function(val) { + return val && typeof val === 'string'; +}; + +/** + * Expose `utils` modules + */ + +module.exports = utils; /***/ }), -/* 492 */ +/* 494 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -49442,14 +49504,14 @@ function define(obj, key, val) { */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(493); + module.exports = __webpack_require__(495); } else { - module.exports = __webpack_require__(496); + module.exports = __webpack_require__(498); } /***/ }), -/* 493 */ +/* 495 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -49458,7 +49520,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(494); +exports = module.exports = __webpack_require__(496); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -49640,7 +49702,7 @@ function localstorage() { /***/ }), -/* 494 */ +/* 496 */ /***/ (function(module, exports, __webpack_require__) { @@ -49656,7 +49718,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(495); +exports.humanize = __webpack_require__(497); /** * The currently active debug mode names, and names to skip. @@ -49848,7 +49910,7 @@ function coerce(val) { /***/ }), -/* 495 */ +/* 497 */ /***/ (function(module, exports) { /** @@ -50006,14 +50068,14 @@ function plural(ms, n, name) { /***/ }), -/* 496 */ +/* 498 */ /***/ (function(module, exports, __webpack_require__) { /** * Module dependencies. */ -var tty = __webpack_require__(497); +var tty = __webpack_require__(499); var util = __webpack_require__(29); /** @@ -50022,7 +50084,7 @@ var util = __webpack_require__(29); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(494); +exports = module.exports = __webpack_require__(496); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -50201,7 +50263,7 @@ function createWritableStdioStream (fd) { case 'PIPE': case 'TCP': - var net = __webpack_require__(498); + var net = __webpack_require__(500); stream = new net.Socket({ fd: fd, readable: false, @@ -50260,19 +50322,19 @@ exports.enable(load()); /***/ }), -/* 497 */ +/* 499 */ /***/ (function(module, exports) { module.exports = require("tty"); /***/ }), -/* 498 */ +/* 500 */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), -/* 499 */ +/* 501 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50283,8 +50345,8 @@ module.exports = require("net"); */ exports.extend = __webpack_require__(430); -exports.SourceMap = __webpack_require__(500); -exports.sourceMapResolve = __webpack_require__(511); +exports.SourceMap = __webpack_require__(502); +exports.sourceMapResolve = __webpack_require__(513); /** * Convert backslash in the given string to forward slashes @@ -50327,7 +50389,7 @@ exports.last = function(arr, n) { /***/ }), -/* 500 */ +/* 502 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -50335,13 +50397,13 @@ exports.last = function(arr, n) { * Licensed under the New BSD license. See LICENSE.txt or: * http://opensource.org/licenses/BSD-3-Clause */ -exports.SourceMapGenerator = __webpack_require__(501).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(507).SourceMapConsumer; -exports.SourceNode = __webpack_require__(510).SourceNode; +exports.SourceMapGenerator = __webpack_require__(503).SourceMapGenerator; +exports.SourceMapConsumer = __webpack_require__(509).SourceMapConsumer; +exports.SourceNode = __webpack_require__(512).SourceNode; /***/ }), -/* 501 */ +/* 503 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -50351,10 +50413,10 @@ exports.SourceNode = __webpack_require__(510).SourceNode; * http://opensource.org/licenses/BSD-3-Clause */ -var base64VLQ = __webpack_require__(502); -var util = __webpack_require__(504); -var ArraySet = __webpack_require__(505).ArraySet; -var MappingList = __webpack_require__(506).MappingList; +var base64VLQ = __webpack_require__(504); +var util = __webpack_require__(506); +var ArraySet = __webpack_require__(507).ArraySet; +var MappingList = __webpack_require__(508).MappingList; /** * An instance of the SourceMapGenerator represents a source map which is @@ -50763,7 +50825,7 @@ exports.SourceMapGenerator = SourceMapGenerator; /***/ }), -/* 502 */ +/* 504 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -50803,7 +50865,7 @@ exports.SourceMapGenerator = SourceMapGenerator; * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var base64 = __webpack_require__(503); +var base64 = __webpack_require__(505); // 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, @@ -50909,7 +50971,7 @@ exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { /***/ }), -/* 503 */ +/* 505 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -50982,7 +51044,7 @@ exports.decode = function (charCode) { /***/ }), -/* 504 */ +/* 506 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -51405,7 +51467,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate /***/ }), -/* 505 */ +/* 507 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -51415,7 +51477,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(504); +var util = __webpack_require__(506); var has = Object.prototype.hasOwnProperty; var hasNativeMap = typeof Map !== "undefined"; @@ -51532,7 +51594,7 @@ exports.ArraySet = ArraySet; /***/ }), -/* 506 */ +/* 508 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -51542,7 +51604,7 @@ exports.ArraySet = ArraySet; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(504); +var util = __webpack_require__(506); /** * Determine whether mappingB is after mappingA with respect to generated @@ -51617,7 +51679,7 @@ exports.MappingList = MappingList; /***/ }), -/* 507 */ +/* 509 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -51627,11 +51689,11 @@ exports.MappingList = MappingList; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(504); -var binarySearch = __webpack_require__(508); -var ArraySet = __webpack_require__(505).ArraySet; -var base64VLQ = __webpack_require__(502); -var quickSort = __webpack_require__(509).quickSort; +var util = __webpack_require__(506); +var binarySearch = __webpack_require__(510); +var ArraySet = __webpack_require__(507).ArraySet; +var base64VLQ = __webpack_require__(504); +var quickSort = __webpack_require__(511).quickSort; function SourceMapConsumer(aSourceMap) { var sourceMap = aSourceMap; @@ -52705,7 +52767,7 @@ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; /***/ }), -/* 508 */ +/* 510 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -52822,7 +52884,7 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { /***/ }), -/* 509 */ +/* 511 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -52942,7 +53004,7 @@ exports.quickSort = function (ary, comparator) { /***/ }), -/* 510 */ +/* 512 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -52952,8 +53014,8 @@ exports.quickSort = function (ary, comparator) { * http://opensource.org/licenses/BSD-3-Clause */ -var SourceMapGenerator = __webpack_require__(501).SourceMapGenerator; -var util = __webpack_require__(504); +var SourceMapGenerator = __webpack_require__(503).SourceMapGenerator; +var util = __webpack_require__(506); // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other // operating systems these days (capturing the result). @@ -53361,17 +53423,17 @@ exports.SourceNode = SourceNode; /***/ }), -/* 511 */ +/* 513 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014, 2015, 2016, 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var sourceMappingURL = __webpack_require__(512) -var resolveUrl = __webpack_require__(513) -var decodeUriComponent = __webpack_require__(514) -var urix = __webpack_require__(516) -var atob = __webpack_require__(517) +var sourceMappingURL = __webpack_require__(514) +var resolveUrl = __webpack_require__(515) +var decodeUriComponent = __webpack_require__(516) +var urix = __webpack_require__(518) +var atob = __webpack_require__(519) @@ -53669,7 +53731,7 @@ module.exports = { /***/ }), -/* 512 */ +/* 514 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell @@ -53732,7 +53794,7 @@ void (function(root, factory) { /***/ }), -/* 513 */ +/* 515 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -53750,13 +53812,13 @@ module.exports = resolveUrl /***/ }), -/* 514 */ +/* 516 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var decodeUriComponent = __webpack_require__(515) +var decodeUriComponent = __webpack_require__(517) function customDecodeUriComponent(string) { // `decodeUriComponent` turns `+` into ` `, but that's not wanted. @@ -53767,7 +53829,7 @@ module.exports = customDecodeUriComponent /***/ }), -/* 515 */ +/* 517 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -53868,7 +53930,7 @@ module.exports = function (encodedURI) { /***/ }), -/* 516 */ +/* 518 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -53891,7 +53953,7 @@ module.exports = urix /***/ }), -/* 517 */ +/* 519 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -53905,7 +53967,7 @@ module.exports = atob.atob = atob; /***/ }), -/* 518 */ +/* 520 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -53914,7 +53976,7 @@ module.exports = atob.atob = atob; var fs = __webpack_require__(23); var path = __webpack_require__(16); var define = __webpack_require__(422); -var utils = __webpack_require__(499); +var utils = __webpack_require__(501); /** * Expose `mixin()`. @@ -54057,19 +54119,19 @@ exports.comment = function(node) { /***/ }), -/* 519 */ +/* 521 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(491); +var use = __webpack_require__(492); var util = __webpack_require__(29); -var Cache = __webpack_require__(520); +var Cache = __webpack_require__(522); var define = __webpack_require__(422); -var debug = __webpack_require__(492)('snapdragon:parser'); -var Position = __webpack_require__(521); -var utils = __webpack_require__(499); +var debug = __webpack_require__(494)('snapdragon:parser'); +var Position = __webpack_require__(523); +var utils = __webpack_require__(501); /** * Create a new `Parser` with the given `input` and `options`. @@ -54597,7 +54659,7 @@ module.exports = Parser; /***/ }), -/* 520 */ +/* 522 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -54704,7 +54766,7 @@ MapCache.prototype.del = function mapDelete(key) { /***/ }), -/* 521 */ +/* 523 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -54725,16 +54787,16 @@ module.exports = function Position(start, parser) { /***/ }), -/* 522 */ +/* 524 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var safe = __webpack_require__(523); -var define = __webpack_require__(529); -var extend = __webpack_require__(530); -var not = __webpack_require__(532); +var safe = __webpack_require__(525); +var define = __webpack_require__(531); +var extend = __webpack_require__(532); +var not = __webpack_require__(534); var MAX_LENGTH = 1024 * 64; /** @@ -54887,10 +54949,10 @@ module.exports.makeRe = makeRe; /***/ }), -/* 523 */ +/* 525 */ /***/ (function(module, exports, __webpack_require__) { -var parse = __webpack_require__(524); +var parse = __webpack_require__(526); var types = parse.types; module.exports = function (re, opts) { @@ -54936,13 +54998,13 @@ function isRegExp (x) { /***/ }), -/* 524 */ +/* 526 */ /***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(525); -var types = __webpack_require__(526); -var sets = __webpack_require__(527); -var positions = __webpack_require__(528); +var util = __webpack_require__(527); +var types = __webpack_require__(528); +var sets = __webpack_require__(529); +var positions = __webpack_require__(530); module.exports = function(regexpStr) { @@ -55224,11 +55286,11 @@ module.exports.types = types; /***/ }), -/* 525 */ +/* 527 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(526); -var sets = __webpack_require__(527); +var types = __webpack_require__(528); +var sets = __webpack_require__(529); // All of these are private and only used by randexp. @@ -55341,7 +55403,7 @@ exports.error = function(regexp, msg) { /***/ }), -/* 526 */ +/* 528 */ /***/ (function(module, exports) { module.exports = { @@ -55357,10 +55419,10 @@ module.exports = { /***/ }), -/* 527 */ +/* 529 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(526); +var types = __webpack_require__(528); var INTS = function() { return [{ type: types.RANGE , from: 48, to: 57 }]; @@ -55445,10 +55507,10 @@ exports.anyChar = function() { /***/ }), -/* 528 */ +/* 530 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(526); +var types = __webpack_require__(528); exports.wordBoundary = function() { return { type: types.POSITION, value: 'b' }; @@ -55468,7 +55530,7 @@ exports.end = function() { /***/ }), -/* 529 */ +/* 531 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -55513,13 +55575,13 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 530 */ +/* 532 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(531); +var isExtendable = __webpack_require__(533); var assignSymbols = __webpack_require__(441); module.exports = Object.assign || function(obj/*, objects*/) { @@ -55580,7 +55642,7 @@ function isEnum(obj, key) { /***/ }), -/* 531 */ +/* 533 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -55601,14 +55663,14 @@ module.exports = function isExtendable(val) { /***/ }), -/* 532 */ +/* 534 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(530); -var safe = __webpack_require__(523); +var extend = __webpack_require__(532); +var safe = __webpack_require__(525); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -55680,14 +55742,14 @@ module.exports = toRegex; /***/ }), -/* 533 */ +/* 535 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(534); -var extglob = __webpack_require__(549); +var nanomatch = __webpack_require__(536); +var extglob = __webpack_require__(551); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -55764,7 +55826,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 534 */ +/* 536 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -55776,16 +55838,16 @@ function escapeExtglobs(compiler) { var util = __webpack_require__(29); var toRegex = __webpack_require__(421); -var extend = __webpack_require__(535); +var extend = __webpack_require__(537); /** * Local dependencies */ -var compilers = __webpack_require__(537); -var parsers = __webpack_require__(538); -var cache = __webpack_require__(541); -var utils = __webpack_require__(543); +var compilers = __webpack_require__(539); +var parsers = __webpack_require__(540); +var cache = __webpack_require__(543); +var utils = __webpack_require__(545); var MAX_LENGTH = 1024 * 64; /** @@ -56609,13 +56671,13 @@ module.exports = nanomatch; /***/ }), -/* 535 */ +/* 537 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(536); +var isExtendable = __webpack_require__(538); var assignSymbols = __webpack_require__(441); module.exports = Object.assign || function(obj/*, objects*/) { @@ -56676,7 +56738,7 @@ function isEnum(obj, key) { /***/ }), -/* 536 */ +/* 538 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -56697,7 +56759,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 537 */ +/* 539 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57043,7 +57105,7 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 538 */ +/* 540 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57051,7 +57113,7 @@ module.exports = function(nanomatch, options) { var regexNot = __webpack_require__(432); var toRegex = __webpack_require__(421); -var isOdd = __webpack_require__(539); +var isOdd = __webpack_require__(541); /** * Characters to use in negation regex (we want to "not" match @@ -57437,7 +57499,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 539 */ +/* 541 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57450,7 +57512,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(540); +var isNumber = __webpack_require__(542); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -57464,7 +57526,7 @@ module.exports = function isOdd(i) { /***/ }), -/* 540 */ +/* 542 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57492,14 +57554,14 @@ module.exports = function isNumber(num) { /***/ }), -/* 541 */ +/* 543 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(542))(); +module.exports = new (__webpack_require__(544))(); /***/ }), -/* 542 */ +/* 544 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57512,7 +57574,7 @@ module.exports = new (__webpack_require__(542))(); -var MapCache = __webpack_require__(520); +var MapCache = __webpack_require__(522); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -57634,7 +57696,7 @@ exports = module.exports = FragmentCache; /***/ }), -/* 543 */ +/* 545 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57647,13 +57709,13 @@ var path = __webpack_require__(16); * Module dependencies */ -var isWindows = __webpack_require__(544)(); +var isWindows = __webpack_require__(546)(); var Snapdragon = __webpack_require__(460); -utils.define = __webpack_require__(545); -utils.diff = __webpack_require__(546); -utils.extend = __webpack_require__(535); -utils.pick = __webpack_require__(547); -utils.typeOf = __webpack_require__(548); +utils.define = __webpack_require__(547); +utils.diff = __webpack_require__(548); +utils.extend = __webpack_require__(537); +utils.pick = __webpack_require__(549); +utils.typeOf = __webpack_require__(550); utils.unique = __webpack_require__(433); /** @@ -58020,7 +58082,7 @@ utils.unixify = function(options) { /***/ }), -/* 544 */ +/* 546 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -58048,7 +58110,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 545 */ +/* 547 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58093,7 +58155,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 546 */ +/* 548 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58147,7 +58209,7 @@ function diffArray(one, two) { /***/ }), -/* 547 */ +/* 549 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58189,7 +58251,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 548 */ +/* 550 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -58324,7 +58386,7 @@ function isBuffer(val) { /***/ }), -/* 549 */ +/* 551 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58342,10 +58404,10 @@ var toRegex = __webpack_require__(421); * Local dependencies */ -var compilers = __webpack_require__(550); -var parsers = __webpack_require__(556); -var Extglob = __webpack_require__(559); -var utils = __webpack_require__(558); +var compilers = __webpack_require__(552); +var parsers = __webpack_require__(558); +var Extglob = __webpack_require__(561); +var utils = __webpack_require__(560); var MAX_LENGTH = 1024 * 64; /** @@ -58662,13 +58724,13 @@ module.exports = extglob; /***/ }), -/* 550 */ +/* 552 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(551); +var brackets = __webpack_require__(553); /** * Extglob compilers @@ -58838,7 +58900,7 @@ module.exports = function(extglob) { /***/ }), -/* 551 */ +/* 553 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58848,14 +58910,14 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(552); -var parsers = __webpack_require__(554); +var compilers = __webpack_require__(554); +var parsers = __webpack_require__(556); /** * Module dependencies */ -var debug = __webpack_require__(492)('expand-brackets'); +var debug = __webpack_require__(494)('expand-brackets'); var extend = __webpack_require__(430); var Snapdragon = __webpack_require__(460); var toRegex = __webpack_require__(421); @@ -59056,13 +59118,13 @@ module.exports = brackets; /***/ }), -/* 552 */ +/* 554 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(553); +var posix = __webpack_require__(555); module.exports = function(brackets) { brackets.compiler @@ -59150,7 +59212,7 @@ module.exports = function(brackets) { /***/ }), -/* 553 */ +/* 555 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59179,13 +59241,13 @@ module.exports = { /***/ }), -/* 554 */ +/* 556 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(555); +var utils = __webpack_require__(557); var define = __webpack_require__(422); /** @@ -59405,7 +59467,7 @@ module.exports.TEXT_REGEX = TEXT_REGEX; /***/ }), -/* 555 */ +/* 557 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59446,15 +59508,15 @@ exports.createRegex = function(pattern, include) { /***/ }), -/* 556 */ +/* 558 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(551); -var define = __webpack_require__(557); -var utils = __webpack_require__(558); +var brackets = __webpack_require__(553); +var define = __webpack_require__(559); +var utils = __webpack_require__(560); /** * Characters to use in text regex (we want to "not" match @@ -59609,7 +59671,7 @@ module.exports = parsers; /***/ }), -/* 557 */ +/* 559 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59647,14 +59709,14 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 558 */ +/* 560 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var regex = __webpack_require__(432); -var Cache = __webpack_require__(542); +var Cache = __webpack_require__(544); /** * Utils @@ -59723,7 +59785,7 @@ utils.createRegex = function(str) { /***/ }), -/* 559 */ +/* 561 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59734,15 +59796,15 @@ utils.createRegex = function(str) { */ var Snapdragon = __webpack_require__(460); -var define = __webpack_require__(557); +var define = __webpack_require__(559); var extend = __webpack_require__(430); /** * Local dependencies */ -var compilers = __webpack_require__(550); -var parsers = __webpack_require__(556); +var compilers = __webpack_require__(552); +var parsers = __webpack_require__(558); /** * Customize Snapdragon parser and renderer @@ -59808,16 +59870,16 @@ module.exports = Extglob; /***/ }), -/* 560 */ +/* 562 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(549); -var nanomatch = __webpack_require__(534); +var extglob = __webpack_require__(551); +var nanomatch = __webpack_require__(536); var regexNot = __webpack_require__(432); -var toRegex = __webpack_require__(522); +var toRegex = __webpack_require__(524); var not; /** @@ -59898,14 +59960,14 @@ function textRegex(pattern) { /***/ }), -/* 561 */ +/* 563 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(542))(); +module.exports = new (__webpack_require__(544))(); /***/ }), -/* 562 */ +/* 564 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59919,11 +59981,11 @@ var path = __webpack_require__(16); */ var Snapdragon = __webpack_require__(460); -utils.define = __webpack_require__(529); -utils.diff = __webpack_require__(546); -utils.extend = __webpack_require__(530); -utils.pick = __webpack_require__(547); -utils.typeOf = __webpack_require__(563); +utils.define = __webpack_require__(531); +utils.diff = __webpack_require__(548); +utils.extend = __webpack_require__(532); +utils.pick = __webpack_require__(549); +utils.typeOf = __webpack_require__(565); utils.unique = __webpack_require__(433); /** @@ -60221,7 +60283,7 @@ utils.unixify = function(options) { /***/ }), -/* 563 */ +/* 565 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -60356,7 +60418,7 @@ function isBuffer(val) { /***/ }), -/* 564 */ +/* 566 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60375,9 +60437,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(565); -var reader_1 = __webpack_require__(578); -var fs_stream_1 = __webpack_require__(582); +var readdir = __webpack_require__(567); +var reader_1 = __webpack_require__(580); +var fs_stream_1 = __webpack_require__(584); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -60438,15 +60500,15 @@ exports.default = ReaderAsync; /***/ }), -/* 565 */ +/* 567 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(566); -const readdirAsync = __webpack_require__(574); -const readdirStream = __webpack_require__(577); +const readdirSync = __webpack_require__(568); +const readdirAsync = __webpack_require__(576); +const readdirStream = __webpack_require__(579); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -60530,7 +60592,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 566 */ +/* 568 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60538,11 +60600,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(567); +const DirectoryReader = __webpack_require__(569); let syncFacade = { - fs: __webpack_require__(572), - forEach: __webpack_require__(573), + fs: __webpack_require__(574), + forEach: __webpack_require__(575), sync: true }; @@ -60571,7 +60633,7 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 567 */ +/* 569 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60580,9 +60642,9 @@ function readdirSync (dir, options, internalOptions) { const Readable = __webpack_require__(28).Readable; const EventEmitter = __webpack_require__(46).EventEmitter; const path = __webpack_require__(16); -const normalizeOptions = __webpack_require__(568); -const stat = __webpack_require__(570); -const call = __webpack_require__(571); +const normalizeOptions = __webpack_require__(570); +const stat = __webpack_require__(572); +const call = __webpack_require__(573); /** * Asynchronously reads the contents of a directory and streams the results @@ -60958,14 +61020,14 @@ module.exports = DirectoryReader; /***/ }), -/* 568 */ +/* 570 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); -const globToRegExp = __webpack_require__(569); +const globToRegExp = __webpack_require__(571); module.exports = normalizeOptions; @@ -61142,7 +61204,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 569 */ +/* 571 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -61279,13 +61341,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 570 */ +/* 572 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(571); +const call = __webpack_require__(573); module.exports = stat; @@ -61360,7 +61422,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 571 */ +/* 573 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61421,14 +61483,14 @@ function callOnce (fn) { /***/ }), -/* 572 */ +/* 574 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(23); -const call = __webpack_require__(571); +const call = __webpack_require__(573); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -61492,7 +61554,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 573 */ +/* 575 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61521,7 +61583,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 574 */ +/* 576 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61529,12 +61591,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(575); -const DirectoryReader = __webpack_require__(567); +const maybe = __webpack_require__(577); +const DirectoryReader = __webpack_require__(569); let asyncFacade = { fs: __webpack_require__(23), - forEach: __webpack_require__(576), + forEach: __webpack_require__(578), async: true }; @@ -61576,7 +61638,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 575 */ +/* 577 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61603,7 +61665,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 576 */ +/* 578 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61639,7 +61701,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 577 */ +/* 579 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61647,11 +61709,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(567); +const DirectoryReader = __webpack_require__(569); let streamFacade = { fs: __webpack_require__(23), - forEach: __webpack_require__(576), + forEach: __webpack_require__(578), async: true }; @@ -61671,16 +61733,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 578 */ +/* 580 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(16); -var deep_1 = __webpack_require__(579); -var entry_1 = __webpack_require__(581); -var pathUtil = __webpack_require__(580); +var deep_1 = __webpack_require__(581); +var entry_1 = __webpack_require__(583); +var pathUtil = __webpack_require__(582); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -61746,13 +61808,13 @@ exports.default = Reader; /***/ }), -/* 579 */ +/* 581 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(580); +var pathUtils = __webpack_require__(582); var patternUtils = __webpack_require__(413); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { @@ -61836,7 +61898,7 @@ exports.default = DeepFilter; /***/ }), -/* 580 */ +/* 582 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61867,13 +61929,13 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 581 */ +/* 583 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(580); +var pathUtils = __webpack_require__(582); var patternUtils = __webpack_require__(413); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { @@ -61959,7 +62021,7 @@ exports.default = EntryFilter; /***/ }), -/* 582 */ +/* 584 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61979,8 +62041,8 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(28); -var fsStat = __webpack_require__(583); -var fs_1 = __webpack_require__(587); +var fsStat = __webpack_require__(585); +var fs_1 = __webpack_require__(589); var FileSystemStream = /** @class */ (function (_super) { __extends(FileSystemStream, _super); function FileSystemStream() { @@ -62030,14 +62092,14 @@ exports.default = FileSystemStream; /***/ }), -/* 583 */ +/* 585 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(584); -const statProvider = __webpack_require__(586); +const optionsManager = __webpack_require__(586); +const statProvider = __webpack_require__(588); /** * Asynchronous API. */ @@ -62068,13 +62130,13 @@ exports.statSync = statSync; /***/ }), -/* 584 */ +/* 586 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(585); +const fsAdapter = __webpack_require__(587); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -62087,7 +62149,7 @@ exports.prepare = prepare; /***/ }), -/* 585 */ +/* 587 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62110,7 +62172,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 586 */ +/* 588 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62162,7 +62224,7 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 587 */ +/* 589 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62193,7 +62255,7 @@ exports.default = FileSystem; /***/ }), -/* 588 */ +/* 590 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62213,9 +62275,9 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(28); -var readdir = __webpack_require__(565); -var reader_1 = __webpack_require__(578); -var fs_stream_1 = __webpack_require__(582); +var readdir = __webpack_require__(567); +var reader_1 = __webpack_require__(580); +var fs_stream_1 = __webpack_require__(584); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -62283,7 +62345,7 @@ exports.default = ReaderStream; /***/ }), -/* 589 */ +/* 591 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62302,9 +62364,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(565); -var reader_1 = __webpack_require__(578); -var fs_sync_1 = __webpack_require__(590); +var readdir = __webpack_require__(567); +var reader_1 = __webpack_require__(580); +var fs_sync_1 = __webpack_require__(592); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -62364,7 +62426,7 @@ exports.default = ReaderSync; /***/ }), -/* 590 */ +/* 592 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62383,8 +62445,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(583); -var fs_1 = __webpack_require__(587); +var fsStat = __webpack_require__(585); +var fs_1 = __webpack_require__(589); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -62430,7 +62492,7 @@ exports.default = FileSystemSync; /***/ }), -/* 591 */ +/* 593 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62446,13 +62508,13 @@ exports.flatten = flatten; /***/ }), -/* 592 */ +/* 594 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var merge2 = __webpack_require__(593); +var merge2 = __webpack_require__(595); /** * Merge multiple streams and propagate their errors into one stream in parallel. */ @@ -62467,7 +62529,7 @@ exports.merge = merge; /***/ }), -/* 593 */ +/* 595 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62581,13 +62643,13 @@ function pauseStreams (streams, options) { /***/ }), -/* 594 */ +/* 596 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); -const pathType = __webpack_require__(595); +const pathType = __webpack_require__(597); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -62653,13 +62715,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 595 */ +/* 597 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(23); -const pify = __webpack_require__(596); +const pify = __webpack_require__(598); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -62702,7 +62764,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 596 */ +/* 598 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62793,7 +62855,7 @@ module.exports = (obj, opts) => { /***/ }), -/* 597 */ +/* 599 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62801,9 +62863,9 @@ module.exports = (obj, opts) => { const fs = __webpack_require__(23); const path = __webpack_require__(16); const fastGlob = __webpack_require__(409); -const gitIgnore = __webpack_require__(598); -const pify = __webpack_require__(599); -const slash = __webpack_require__(600); +const gitIgnore = __webpack_require__(600); +const pify = __webpack_require__(601); +const slash = __webpack_require__(602); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -62901,7 +62963,7 @@ module.exports.sync = options => { /***/ }), -/* 598 */ +/* 600 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -63370,7 +63432,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 599 */ +/* 601 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63445,7 +63507,7 @@ module.exports = (input, options) => { /***/ }), -/* 600 */ +/* 602 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63463,17 +63525,17 @@ module.exports = input => { /***/ }), -/* 601 */ +/* 603 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); const {constants: fsConstants} = __webpack_require__(23); -const {Buffer} = __webpack_require__(602); -const CpFileError = __webpack_require__(604); -const fs = __webpack_require__(606); -const ProgressEmitter = __webpack_require__(608); +const {Buffer} = __webpack_require__(604); +const CpFileError = __webpack_require__(606); +const fs = __webpack_require__(608); +const ProgressEmitter = __webpack_require__(610); const cpFile = (source, destination, options) => { if (!source || !destination) { @@ -63627,11 +63689,11 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 602 */ +/* 604 */ /***/ (function(module, exports, __webpack_require__) { /* eslint-disable node/no-deprecated-api */ -var buffer = __webpack_require__(603) +var buffer = __webpack_require__(605) var Buffer = buffer.Buffer // alternative to using Object.keys for old browsers @@ -63695,18 +63757,18 @@ SafeBuffer.allocUnsafeSlow = function (size) { /***/ }), -/* 603 */ +/* 605 */ /***/ (function(module, exports) { module.exports = require("buffer"); /***/ }), -/* 604 */ +/* 606 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(605); +const NestedError = __webpack_require__(607); class CpFileError extends NestedError { constructor(message, nested) { @@ -63720,7 +63782,7 @@ module.exports = CpFileError; /***/ }), -/* 605 */ +/* 607 */ /***/ (function(module, exports, __webpack_require__) { var inherits = __webpack_require__(44); @@ -63774,15 +63836,15 @@ module.exports = NestedError; /***/ }), -/* 606 */ +/* 608 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(22); const makeDir = __webpack_require__(115); -const pify = __webpack_require__(607); -const CpFileError = __webpack_require__(604); +const pify = __webpack_require__(609); +const CpFileError = __webpack_require__(606); const fsP = pify(fs); @@ -63927,7 +63989,7 @@ if (fs.copyFileSync) { /***/ }), -/* 607 */ +/* 609 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64002,7 +64064,7 @@ module.exports = (input, options) => { /***/ }), -/* 608 */ +/* 610 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64043,12 +64105,12 @@ module.exports = ProgressEmitter; /***/ }), -/* 609 */ +/* 611 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(610); +const NestedError = __webpack_require__(612); class CpyError extends NestedError { constructor(message, nested) { @@ -64062,7 +64124,7 @@ module.exports = CpyError; /***/ }), -/* 610 */ +/* 612 */ /***/ (function(module, exports, __webpack_require__) { var inherits = __webpack_require__(29).inherits; @@ -64118,7 +64180,7 @@ module.exports = NestedError; /***/ }), -/* 611 */ +/* 613 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; diff --git a/renovate.json5 b/renovate.json5 index e8fd7b6ceda50..ed3a7be209f31 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -647,6 +647,14 @@ '@types/color', ], }, + { + groupSlug: 'cytoscape', + groupName: 'cytoscape related packages', + packageNames: [ + 'cytoscape', + '@types/cytoscape', + ], + }, { groupSlug: 'fancy-log', groupName: 'fancy-log related packages', diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 4fe50baaf83be..727c51f704431 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -63,6 +63,7 @@ export const LICENSE_WHITELIST = [ 'MIT/X11', 'new BSD, and MIT', '(OFL-1.1 AND MIT)', + 'PSF', 'Public Domain', 'Unlicense', 'WTFPL OR ISC', diff --git a/x-pack/legacy/plugins/apm/index.ts b/x-pack/legacy/plugins/apm/index.ts index 95c872c20aeb1..4d3d2b210bbae 100644 --- a/x-pack/legacy/plugins/apm/index.ts +++ b/x-pack/legacy/plugins/apm/index.ts @@ -43,6 +43,7 @@ export const apm: LegacyPluginInitializer = kibana => { apmUiEnabled: config.get('xpack.apm.ui.enabled'), // TODO: rename to apm_oss.indexPatternTitle in 7.0 (breaking change) apmIndexPatternTitle: config.get('apm_oss.indexPattern'), + apmServiceMapEnabled: config.get('xpack.apm.serviceMapEnabled'), apmTransactionIndices: config.get('apm_oss.transactionIndices') }; }, @@ -70,7 +71,10 @@ export const apm: LegacyPluginInitializer = kibana => { // buckets minimumBucketSize: Joi.number().default(15), - bucketTargetCount: Joi.number().default(15) + bucketTargetCount: Joi.number().default(15), + + // service map + serviceMapEnabled: Joi.boolean().default(false) }).default(); }, diff --git a/x-pack/legacy/plugins/apm/public/components/app/Home/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/Home/index.tsx index 7d54ebf65ae1c..f562f158f9bf8 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/Home/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/Home/index.tsx @@ -13,6 +13,7 @@ import { EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { npStart } from 'ui/new_platform'; import React from 'react'; import { $ElementType } from 'utility-types'; import { ApmHeader } from '../../shared/ApmHeader'; @@ -23,6 +24,8 @@ import { ServiceOverviewLink } from '../../shared/Links/apm/ServiceOverviewLink' import { TraceOverviewLink } from '../../shared/Links/apm/TraceOverviewLink'; import { EuiTabLink } from '../../shared/EuiTabLink'; import { SettingsLink } from '../../shared/Links/apm/SettingsLink'; +import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; +import { ServiceMap } from '../ServiceMap'; const homeTabs = [ { @@ -49,12 +52,26 @@ const homeTabs = [ } ]; +if (npStart.core.injectedMetadata.getInjectedVar('apmServiceMapEnabled')) { + homeTabs.push({ + link: ( + + {i18n.translate('xpack.apm.home.serviceMapTabLabel', { + defaultMessage: 'Service Map' + })} + + ), + render: () => , + name: 'service-map' + }); +} + const SETTINGS_LINK_LABEL = i18n.translate('xpack.apm.settingsLinkLabel', { defaultMessage: 'Settings' }); interface Props { - tab: 'traces' | 'services'; + tab: 'traces' | 'services' | 'service-map'; } export function Home({ tab }: Props) { diff --git a/x-pack/legacy/plugins/apm/public/components/app/Main/route_config/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/Main/route_config/index.tsx index 528870da12cdc..c66c73b9f98fb 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/Main/route_config/index.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/Main/route_config/index.tsx @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { Redirect, RouteComponentProps } from 'react-router-dom'; +import { npStart } from 'ui/new_platform'; import { ErrorGroupDetails } from '../../ErrorGroupDetails'; import { ServiceDetails } from '../../ServiceDetails'; import { TransactionDetails } from '../../TransactionDetails'; @@ -149,3 +150,26 @@ export const routes: BreadcrumbRoute[] = [ name: RouteName.TRANSACTION_NAME } ]; + +if (npStart.core.injectedMetadata.getInjectedVar('apmServiceMapEnabled')) { + routes.push( + { + exact: true, + path: '/service-map', + component: () => , + breadcrumb: i18n.translate('xpack.apm.breadcrumb.serviceMapTitle', { + defaultMessage: 'Service Map' + }), + name: RouteName.SERVICE_MAP + }, + { + exact: true, + path: '/services/:serviceName/service-map', + component: () => , + breadcrumb: i18n.translate('xpack.apm.breadcrumb.serviceMapTitle', { + defaultMessage: 'Service Map' + }), + name: RouteName.SINGLE_SERVICE_MAP + } + ); +} diff --git a/x-pack/legacy/plugins/apm/public/components/app/Main/route_config/route_names.tsx b/x-pack/legacy/plugins/apm/public/components/app/Main/route_config/route_names.tsx index 26c68b835ff03..3af5b217ca738 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/Main/route_config/route_names.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/Main/route_config/route_names.tsx @@ -7,6 +7,8 @@ export enum RouteName { HOME = 'home', SERVICES = 'services', + SERVICE_MAP = 'service-map', + SINGLE_SERVICE_MAP = 'single-service-map', TRACES = 'traces', SERVICE = 'service', TRANSACTIONS = 'transactions', diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx index fd9002e0edd94..1fc83217f2a1c 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceDetailTabs.tsx @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { EuiTabs, EuiSpacer } from '@elastic/eui'; +import { npStart } from 'ui/new_platform'; import { ErrorGroupOverview } from '../ErrorGroupOverview'; import { TransactionOverview } from '../TransactionOverview'; import { ServiceMetrics } from '../ServiceMetrics'; @@ -19,9 +20,11 @@ import { MetricOverviewLink } from '../../shared/Links/apm/MetricOverviewLink'; import { ServiceNodeOverviewLink } from '../../shared/Links/apm/ServiceNodeOverviewLink'; import { ServiceNodeOverview } from '../ServiceNodeOverview'; import { useAgentName } from '../../../hooks/useAgentName'; +import { ServiceMap } from '../ServiceMap'; +import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink'; interface Props { - tab: 'transactions' | 'errors' | 'metrics' | 'nodes'; + tab: 'transactions' | 'errors' | 'metrics' | 'nodes' | 'service-map'; } export function ServiceDetailTabs({ tab }: Props) { @@ -90,6 +93,22 @@ export function ServiceDetailTabs({ tab }: Props) { tabs.push(metricsTab); } + const serviceMapTab = { + link: ( + + {i18n.translate('xpack.apm.home.serviceMapTabLabel', { + defaultMessage: 'Service Map' + })} + + ), + render: () => , + name: 'service-map' + }; + + if (npStart.core.injectedMetadata.getInjectedVar('apmServiceMapEnabled')) { + tabs.push(serviceMapTab); + } + const selectedTab = tabs.find(serviceTab => serviceTab.name === tab); return ( diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Controls.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Controls.tsx new file mode 100644 index 0000000000000..f7166bd0cec5c --- /dev/null +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMap/Controls.tsx @@ -0,0 +1,108 @@ +/* + * 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, { useContext, useState, useEffect } from 'react'; +import { EuiButtonIcon, EuiPanel } from '@elastic/eui'; +import theme from '@elastic/eui/dist/eui_theme_light.json'; +import styled from 'styled-components'; +import { i18n } from '@kbn/i18n'; +import { CytoscapeContext } from './Cytoscape'; +import { FullscreenPanel } from './FullscreenPanel'; + +const Container = styled('div')` + left: ${theme.gutterTypes.gutterMedium}; + position: absolute; + top: ${theme.gutterTypes.gutterSmall}; +`; + +const Button = styled(EuiButtonIcon)` + display: block; + margin: ${theme.paddingSizes.xs}; +`; + +const ZoomInButton = styled(Button)` + margin-bottom: ${theme.paddingSizes.s}; +`; + +const ZoomPanel = styled(EuiPanel)` + margin-bottom: ${theme.paddingSizes.s}; +`; + +const duration = parseInt(theme.euiAnimSpeedFast, 10); +const steps = 5; + +function doZoom(cy: cytoscape.Core | undefined, increment: number) { + if (cy) { + const level = cy.zoom() + increment; + cy.animate({ + duration, + zoom: { level, position: cy.$('.primary').position() } + }); + } +} + +export function Controls() { + const cy = useContext(CytoscapeContext); + + const [zoom, setZoom] = useState((cy && cy.zoom()) || 1); + + useEffect(() => { + if (cy) { + cy.on('zoom', event => { + setZoom(event.cy.zoom()); + }); + } + }, [cy]); + + function zoomIn() { + doZoom(cy, increment); + } + + function zoomOut() { + doZoom(cy, -increment); + } + + if (!cy) { + return null; + } + + const maxZoom = cy.maxZoom(); + const isMaxZoom = zoom === maxZoom; + const minZoom = cy.minZoom(); + const isMinZoom = zoom === minZoom; + const increment = (maxZoom - minZoom) / steps; + const mapDomElement = cy.container(); + const zoomInLabel = i18n.translate('xpack.apm.serviceMap.zoomIn', { + defaultMessage: 'Zoom in' + }); + const zoomOutLabel = i18n.translate('xpack.apm.serviceMap.zoomOut', { + defaultMessage: 'Zoom out' + }); + + return ( + + + +