diff --git a/package.json b/package.json index 0bf173d9603e7..d5f738fad0400 100644 --- a/package.json +++ b/package.json @@ -126,7 +126,7 @@ "@elastic/apm-rum": "^5.1.1", "@elastic/charts": "19.2.0", "@elastic/datemath": "5.0.3", - "@elastic/ems-client": "7.8.0", + "@elastic/ems-client": "7.9.3", "@elastic/eui": "24.1.0", "@elastic/filesaver": "1.1.2", "@elastic/good": "8.1.1-kibana2", diff --git a/x-pack/package.json b/x-pack/package.json index fb708ab09d841..6a84bcf449455 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -189,7 +189,7 @@ "@babel/runtime": "^7.9.2", "@elastic/apm-rum-react": "^1.1.1", "@elastic/datemath": "5.0.3", - "@elastic/ems-client": "7.8.0", + "@elastic/ems-client": "7.9.3", "@elastic/eui": "24.1.0", "@elastic/filesaver": "1.1.2", "@elastic/maki": "6.3.0", diff --git a/x-pack/plugins/maps/public/classes/fields/ems_file_field.ts b/x-pack/plugins/maps/public/classes/fields/ems_file_field.ts index 73d6c1ef9f790..2e9c5c9fe60c2 100644 --- a/x-pack/plugins/maps/public/classes/fields/ems_file_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/ems_file_field.ts @@ -30,12 +30,6 @@ export class EMSFileField extends AbstractField implements IField { } async getLabel(): Promise { - const emsFileLayer = await this._source.getEMSFileLayer(); - // TODO remove any and @ts-ignore when emsFileLayer type defined - // @ts-ignore - const emsFields: any[] = emsFileLayer.getFieldsInLanguage(); - // Map EMS field name to language specific label - const emsField = emsFields.find((field) => field.name === this.getName()); - return emsField ? emsField.description : this.getName(); + return this._source.getEmsFieldLabel(this.getName()); } } diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx index e398af4acea3b..a78a49032503b 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/create_source_editor.tsx @@ -8,8 +8,8 @@ import React, { Component } from 'react'; import { EuiComboBox, EuiComboBoxOptionOption, EuiFormRow } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -// @ts-ignore -import { getEMSClient } from '../../../meta'; +import { FileLayer } from '@elastic/ems-client'; +import { getEmsFileLayers } from '../../../meta'; import { getEmsUnavailableMessage } from '../ems_unavailable_message'; import { EMSFileSourceDescriptor } from '../../../../common/descriptor_types'; @@ -33,15 +33,10 @@ export class EMSFileCreateSourceEditor extends Component { }; _loadFileOptions = async () => { - // @ts-ignore - const emsClient = getEMSClient(); - // @ts-ignore - const fileLayers: unknown[] = await emsClient.getFileLayers(); + const fileLayers: FileLayer[] = await getEmsFileLayers(); const options = fileLayers.map((fileLayer) => { return { - // @ts-ignore value: fileLayer.getId(), - // @ts-ignore label: fileLayer.getDisplayName(), }; }); diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.test.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.test.tsx index 24c111a72ac05..52524d0c9a5fa 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.test.tsx @@ -11,17 +11,8 @@ jest.mock('../../layers/vector_layer/vector_layer', () => {}); function makeEMSFileSource(tooltipProperties: string[]) { const emsFileSource = new EMSFileSource({ tooltipProperties }); - emsFileSource.getEMSFileLayer = async () => { - return { - getFieldsInLanguage() { - return [ - { - name: 'iso2', - description: 'ISO 2 CODE', - }, - ]; - }, - }; + emsFileSource.getEmsFieldLabel = async (name: string) => { + return name === 'iso2' ? 'ISO 2 CODE' : name; }; return emsFileSource; } diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.tsx index 94f5bb0d2ba07..f7fb0078764c4 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/ems_file_source.tsx @@ -8,12 +8,12 @@ import React, { ReactElement } from 'react'; import { i18n } from '@kbn/i18n'; import { Feature } from 'geojson'; import { Adapters } from 'src/plugins/inspector/public'; +import { FileLayer } from '@elastic/ems-client'; import { Attribution, ImmutableSourceProperty, SourceEditorArgs } from '../source'; import { AbstractVectorSource, GeoJsonWithMeta, IVectorSource } from '../vector_source'; import { VECTOR_SHAPE_TYPES } from '../vector_feature_types'; import { SOURCE_TYPES, FIELD_ORIGIN } from '../../../../common/constants'; -// @ts-ignore -import { getEMSClient } from '../../../meta'; +import { getEmsFileLayers } from '../../../meta'; import { getDataSourceLabel } from '../../../../common/i18n_getters'; import { UpdateSourceEditor } from './update_source_editor'; import { EMSFileField } from '../../fields/ems_file_field'; @@ -23,7 +23,7 @@ import { EMSFileSourceDescriptor } from '../../../../common/descriptor_types'; import { ITooltipProperty } from '../../tooltips/tooltip_property'; export interface IEmsFileSource extends IVectorSource { - getEMSFileLayer(): Promise; + getEmsFieldLabel(emsFieldName: string): Promise; createField({ fieldName }: { fieldName: string }): IField; } @@ -72,13 +72,9 @@ export class EMSFileSource extends AbstractVectorSource implements IEmsFileSourc ); } - async getEMSFileLayer(): Promise { - // @ts-ignore - const emsClient = getEMSClient(); - // @ts-ignore - const emsFileLayers = await emsClient.getFileLayers(); + async getEMSFileLayer(): Promise { + const emsFileLayers = await getEmsFileLayers(); const emsFileLayer = emsFileLayers.find( - // @ts-ignore (fileLayer) => fileLayer.getId() === this._descriptor.id ); if (!emsFileLayer) { @@ -94,19 +90,25 @@ export class EMSFileSource extends AbstractVectorSource implements IEmsFileSourc return emsFileLayer; } + // Map EMS field name to language specific label + async getEmsFieldLabel(emsFieldName: string): Promise { + const emsFileLayer = await this.getEMSFileLayer(); + const emsFields = emsFileLayer.getFieldsInLanguage(); + + const emsField = emsFields.find((field) => field.name === emsFieldName); + return emsField ? emsField.description : emsFieldName; + } + async getGeoJsonWithMeta(): Promise { const emsFileLayer = await this.getEMSFileLayer(); // @ts-ignore const featureCollection = await AbstractVectorSource.getGeoJson({ - // @ts-ignore format: emsFileLayer.getDefaultFormatType(), featureCollectionPath: 'data', - // @ts-ignore fetchUrl: emsFileLayer.getDefaultFormatUrl(), }); - // @ts-ignore - const emsIdField = emsFileLayer._config.fields.find((field) => { + const emsIdField = emsFileLayer.getFields().find((field) => { return field.type === 'id'; }); featureCollection.features.forEach((feature: Feature, index: number) => { @@ -123,7 +125,6 @@ export class EMSFileSource extends AbstractVectorSource implements IEmsFileSourc let emsLink; try { const emsFileLayer = await this.getEMSFileLayer(); - // @ts-ignore emsLink = emsFileLayer.getEMSHotLink(); } catch (error) { // ignore error if EMS layer id could not be found @@ -147,7 +148,6 @@ export class EMSFileSource extends AbstractVectorSource implements IEmsFileSourc async getDisplayName(): Promise { try { const emsFileLayer = await this.getEMSFileLayer(); - // @ts-ignore return emsFileLayer.getDisplayName(); } catch (error) { return this._descriptor.id; @@ -156,15 +156,12 @@ export class EMSFileSource extends AbstractVectorSource implements IEmsFileSourc async getAttributions(): Promise { const emsFileLayer = await this.getEMSFileLayer(); - // @ts-ignore return emsFileLayer.getAttributions(); } async getLeftJoinFields() { const emsFileLayer = await this.getEMSFileLayer(); - // @ts-ignore const fields = emsFileLayer.getFieldsInLanguage(); - // @ts-ignore return fields.map((f) => this.createField({ fieldName: f.name })); } diff --git a/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx index daeb1f8bc6b2b..ac69505a9bed5 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/ems_file_source/update_source_editor.tsx @@ -8,8 +8,7 @@ import React, { Component, Fragment } from 'react'; import { EuiTitle, EuiPanel, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { TooltipSelector } from '../../../components/tooltip_selector'; -// @ts-ignore -import { getEMSClient } from '../../../meta'; +import { getEmsFileLayers } from '../../../meta'; import { IEmsFileSource } from './ems_file_source'; import { IField } from '../../fields/field'; import { OnSourceChangeArgs } from '../../../connected_components/layer_panel/view'; @@ -42,22 +41,18 @@ export class UpdateSourceEditor extends Component { } async loadFields() { - let fields; + let fields: IField[] = []; try { - // @ts-ignore - const emsClient = getEMSClient(); - // @ts-ignore - const emsFiles = await emsClient.getFileLayers(); - // @ts-ignore - const taregetEmsFile = emsFiles.find((emsFile) => emsFile.getId() === this.props.layerId); - // @ts-ignore - const emsFields = taregetEmsFile.getFieldsInLanguage(); - // @ts-ignore - fields = emsFields.map((field) => this.props.source.createField({ fieldName: field.name })); + const emsFiles = await getEmsFileLayers(); + const targetEmsFile = emsFiles.find((emsFile) => emsFile.getId() === this.props.layerId); + if (targetEmsFile) { + fields = targetEmsFile + .getFieldsInLanguage() + .map((field) => this.props.source.createField({ fieldName: field.name })); + } } catch (e) { // When a matching EMS-config cannot be found, the source already will have thrown errors during the data request. // This will propagate to the vector-layer and be displayed in the UX - fields = []; } if (this._isMounted) { diff --git a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.js b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.js index 36c9e424a8b22..83c87eb53d4fe 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.js +++ b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.js @@ -7,7 +7,7 @@ import _ from 'lodash'; import React from 'react'; import { AbstractTMSSource } from '../tms_source'; -import { getEMSClient } from '../../../meta'; +import { getEmsTmsServices } from '../../../meta'; import { UpdateSourceEditor } from './update_source_editor'; import { i18n } from '@kbn/i18n'; import { getDataSourceLabel } from '../../../../common/i18n_getters'; @@ -66,8 +66,7 @@ export class EMSTMSSource extends AbstractTMSSource { } async _getEMSTMSService() { - const emsClient = getEMSClient(); - const emsTMSServices = await emsClient.getTMSServices(); + const emsTMSServices = await getEmsTmsServices(); const emsTileLayerId = this.getTileLayerId(); const tmsService = emsTMSServices.find((tmsService) => tmsService.getId() === emsTileLayerId); if (!tmsService) { diff --git a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.test.js b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.test.js index 08c54299d721b..2f466add28262 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.test.js +++ b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/ems_tms_source.test.js @@ -6,7 +6,7 @@ jest.mock('../../../meta', () => { return { - getEMSClient: () => { + getEmsTmsServices: () => { class MockTMSService { constructor(config) { this._config = config; @@ -19,20 +19,16 @@ jest.mock('../../../meta', () => { } } - return { - async getTMSServices() { - return [ - new MockTMSService({ - id: 'road_map', - attributionMarkdown: '[foobar](http://foobar.org) | [foobaz](http://foobaz.org)', - }), - new MockTMSService({ - id: 'satellite', - attributionMarkdown: '[satellite](http://satellite.org)', - }), - ]; - }, - }; + return [ + new MockTMSService({ + id: 'road_map', + attributionMarkdown: '[foobar](http://foobar.org) | [foobaz](http://foobaz.org)', + }), + new MockTMSService({ + id: 'satellite', + attributionMarkdown: '[satellite](http://satellite.org)', + }), + ]; }, }; }); diff --git a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js index 4d5d6655609c1..3931e441ff254 100644 --- a/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js +++ b/x-pack/plugins/maps/public/classes/sources/ems_tms_source/tile_service_select.js @@ -7,7 +7,7 @@ import React from 'react'; import { EuiSelect, EuiFormRow } from '@elastic/eui'; -import { getEMSClient } from '../../../meta'; +import { getEmsTmsServices } from '../../../meta'; import { getEmsUnavailableMessage } from '../ems_unavailable_message'; import { i18n } from '@kbn/i18n'; @@ -29,8 +29,7 @@ export class TileServiceSelect extends React.Component { } _loadTmsOptions = async () => { - const emsClient = getEMSClient(); - const emsTMSServices = await emsClient.getTMSServices(); + const emsTMSServices = await getEmsTmsServices(); if (!this._isMounted) { return; diff --git a/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/kibana_regionmap_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/kibana_regionmap_layer_wizard.tsx index b778dc0076459..ca78aaefe404f 100644 --- a/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/kibana_regionmap_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/kibana_regionmap_source/kibana_regionmap_layer_wizard.tsx @@ -12,13 +12,12 @@ import { KibanaRegionmapSource, sourceTitle } from './kibana_regionmap_source'; import { VectorLayer } from '../../layers/vector_layer/vector_layer'; // @ts-ignore import { CreateSourceEditor } from './create_source_editor'; -// @ts-ignore import { getKibanaRegionList } from '../../../meta'; export const kibanaRegionMapLayerWizardConfig: LayerWizard = { - checkVisibility: () => { + checkVisibility: async () => { const regions = getKibanaRegionList(); - return regions.length; + return regions.length > 0; }, description: i18n.translate('xpack.maps.source.kbnRegionMapDescription', { defaultMessage: 'Vector data from hosted GeoJSON configured in kibana.yml', diff --git a/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/kibana_base_map_layer_wizard.tsx b/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/kibana_base_map_layer_wizard.tsx index 227c0182b98de..84d2e5e74fa9a 100644 --- a/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/kibana_base_map_layer_wizard.tsx +++ b/x-pack/plugins/maps/public/classes/sources/kibana_tilemap_source/kibana_base_map_layer_wizard.tsx @@ -12,12 +12,12 @@ import { CreateSourceEditor } from './create_source_editor'; // @ts-ignore import { KibanaTilemapSource, sourceTitle } from './kibana_tilemap_source'; import { TileLayer } from '../../layers/tile_layer/tile_layer'; -// @ts-ignore import { getKibanaTileMap } from '../../../meta'; export const kibanaBasemapLayerWizardConfig: LayerWizard = { checkVisibility: async () => { const tilemap = getKibanaTileMap(); + // @ts-ignore return !!tilemap.url; }, description: i18n.translate('xpack.maps.source.kbnTMSDescription', { diff --git a/x-pack/plugins/maps/public/meta.js b/x-pack/plugins/maps/public/meta.js deleted file mode 100644 index 46c5e5cda3617..0000000000000 --- a/x-pack/plugins/maps/public/meta.js +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - getHttp, - getLicenseId, - getIsEmsEnabled, - getRegionmapLayers, - getTilemap, - getEmsFileApiUrl, - getEmsTileApiUrl, - getEmsLandingPageUrl, - getEmsFontLibraryUrl, - getProxyElasticMapsServiceInMaps, - getKibanaVersion, -} from './kibana_services'; -import { - GIS_API_PATH, - EMS_FILES_CATALOGUE_PATH, - EMS_TILES_CATALOGUE_PATH, - EMS_GLYPHS_PATH, - EMS_APP_NAME, - FONTS_API_PATH, -} from '../common/constants'; -import { i18n } from '@kbn/i18n'; -import { EMSClient } from '@elastic/ems-client'; - -import fetch from 'node-fetch'; - -const GIS_API_RELATIVE = `../${GIS_API_PATH}`; - -export function getKibanaRegionList() { - return getRegionmapLayers(); -} - -export function getKibanaTileMap() { - return getTilemap(); -} - -function relativeToAbsolute(url) { - const a = document.createElement('a'); - a.setAttribute('href', url); - return a.href; -} - -function fetchFunction(...args) { - return fetch(...args); -} - -let emsClient = null; -let latestLicenseId = null; -export function getEMSClient() { - if (!emsClient) { - const isEmsEnabled = getIsEmsEnabled(); - if (isEmsEnabled) { - const proxyElasticMapsServiceInMaps = getProxyElasticMapsServiceInMaps(); - const proxyPath = ''; - const tileApiUrl = proxyElasticMapsServiceInMaps - ? relativeToAbsolute(`${GIS_API_RELATIVE}/${EMS_TILES_CATALOGUE_PATH}`) - : getEmsTileApiUrl(); - const fileApiUrl = proxyElasticMapsServiceInMaps - ? relativeToAbsolute(`${GIS_API_RELATIVE}/${EMS_FILES_CATALOGUE_PATH}`) - : getEmsFileApiUrl(); - - emsClient = new EMSClient({ - language: i18n.getLocale(), - appVersion: getKibanaVersion(), - appName: EMS_APP_NAME, - tileApiUrl, - fileApiUrl, - landingPageUrl: getEmsLandingPageUrl(), - fetchFunction: fetchFunction, //import this from client-side, so the right instance is returned (bootstrapped from common/* would not work - proxyPath, - }); - } else { - //EMS is turned off. Mock API. - emsClient = { - async getFileLayers() { - return []; - }, - async getTMSServices() { - return []; - }, - addQueryParams() {}, - }; - } - } - const licenseId = getLicenseId(); - if (latestLicenseId !== licenseId) { - latestLicenseId = licenseId; - emsClient.addQueryParams({ license: licenseId }); - } - return emsClient; -} - -export function getGlyphUrl() { - if (!getIsEmsEnabled()) { - return getHttp().basePath.prepend(`/${FONTS_API_PATH}/{fontstack}/{range}`); - } - return getProxyElasticMapsServiceInMaps() - ? relativeToAbsolute(`../${GIS_API_PATH}/${EMS_TILES_CATALOGUE_PATH}/${EMS_GLYPHS_PATH}`) + - `/{fontstack}/{range}` - : getEmsFontLibraryUrl(); -} - -export function isRetina() { - return window.devicePixelRatio === 2; -} diff --git a/x-pack/plugins/maps/public/meta.ts b/x-pack/plugins/maps/public/meta.ts new file mode 100644 index 0000000000000..54c5eac7fe1b0 --- /dev/null +++ b/x-pack/plugins/maps/public/meta.ts @@ -0,0 +1,111 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; +import { EMSClient, FileLayer, TMSService } from '@elastic/ems-client'; + +import fetch from 'node-fetch'; +import { + GIS_API_PATH, + EMS_FILES_CATALOGUE_PATH, + EMS_TILES_CATALOGUE_PATH, + EMS_GLYPHS_PATH, + EMS_APP_NAME, + FONTS_API_PATH, +} from '../common/constants'; +import { + getHttp, + getLicenseId, + getIsEmsEnabled, + getRegionmapLayers, + getTilemap, + getEmsFileApiUrl, + getEmsTileApiUrl, + getEmsLandingPageUrl, + getEmsFontLibraryUrl, + getProxyElasticMapsServiceInMaps, + getKibanaVersion, +} from './kibana_services'; + +const GIS_API_RELATIVE = `../${GIS_API_PATH}`; + +export function getKibanaRegionList(): unknown[] { + return getRegionmapLayers(); +} + +export function getKibanaTileMap(): unknown { + return getTilemap(); +} + +export async function getEmsFileLayers(): Promise { + if (!getIsEmsEnabled()) { + return []; + } + + return getEMSClient().getFileLayers(); +} + +export async function getEmsTmsServices(): Promise { + if (!getIsEmsEnabled()) { + return []; + } + + return getEMSClient().getTMSServices(); +} + +function relativeToAbsolute(url: string): string { + const a = document.createElement('a'); + a.setAttribute('href', url); + return a.href; +} + +let emsClient: EMSClient | null = null; +let latestLicenseId: string | null = null; +export function getEMSClient(): EMSClient { + if (!emsClient) { + const proxyElasticMapsServiceInMaps = getProxyElasticMapsServiceInMaps(); + const proxyPath = ''; + const tileApiUrl = proxyElasticMapsServiceInMaps + ? relativeToAbsolute(`${GIS_API_RELATIVE}/${EMS_TILES_CATALOGUE_PATH}`) + : getEmsTileApiUrl(); + const fileApiUrl = proxyElasticMapsServiceInMaps + ? relativeToAbsolute(`${GIS_API_RELATIVE}/${EMS_FILES_CATALOGUE_PATH}`) + : getEmsFileApiUrl(); + + emsClient = new EMSClient({ + language: i18n.getLocale(), + appVersion: getKibanaVersion(), + appName: EMS_APP_NAME, + tileApiUrl, + fileApiUrl, + landingPageUrl: getEmsLandingPageUrl(), + fetchFunction(url: string) { + return fetch(url); + }, + proxyPath, + }); + } + const licenseId = getLicenseId(); + if (latestLicenseId !== licenseId) { + latestLicenseId = licenseId; + emsClient.addQueryParams({ license: licenseId }); + } + return emsClient; +} + +export function getGlyphUrl(): string { + if (!getIsEmsEnabled()) { + return getHttp().basePath.prepend(`/${FONTS_API_PATH}/{fontstack}/{range}`); + } + return getProxyElasticMapsServiceInMaps() + ? relativeToAbsolute(`../${GIS_API_PATH}/${EMS_TILES_CATALOGUE_PATH}/${EMS_GLYPHS_PATH}`) + + `/{fontstack}/{range}` + : getEmsFontLibraryUrl(); +} + +export function isRetina(): boolean { + return window.devicePixelRatio === 2; +} diff --git a/yarn.lock b/yarn.lock index f9f15ab79310d..df16cd891ea6d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1297,10 +1297,10 @@ once "^1.4.0" pump "^3.0.0" -"@elastic/ems-client@7.8.0": - version "7.8.0" - resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.8.0.tgz#8cc309bc8128c03a78e876b43bf04f4d2b4789c5" - integrity sha512-+6WjxZy/mhVWXTdSYjHd+ArsvH1s7GEummaGq9DlnCW6CyGIYkYxOISKpuytReeYhhMk7F06f/GKw+8ivi2zPQ== +"@elastic/ems-client@7.9.3": + version "7.9.3" + resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.9.3.tgz#71b79914f76e347f050ead8474ad65d761e94a8a" + integrity sha512-aun5rW9TQgWLVH77xBLLhempT3P+6AeQIEyK/CWYuVfCDpHfDxzMKWgQ076a7rSUqF059ayDGZbyOxf7l0M2Sw== dependencies: lodash "^4.17.15" semver "^6.3.0"