@elastic/ems-client 8.5.1 → 8.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.buildkite/pipeline.yml +1 -1
- package/.husky/pre-commit +1 -0
- package/CHANGELOG.md +5 -0
- package/eslint.config.mjs +25 -0
- package/package.json +28 -28
- package/src/ems_client.ts +6 -2
- package/src/tms_service.ts +18 -12
- package/target/ems_client.d.ts +16 -16
- package/target/ems_client.js +318 -0
- package/target/ems_service.js +47 -0
- package/target/file_layer.d.ts +1 -1
- package/target/file_layer.js +176 -0
- package/target/index.js +16 -0
- package/target/node/ems_client.js +15 -11
- package/target/node/ems_service.js +8 -8
- package/target/node/file_layer.js +10 -10
- package/target/node/tms_service.js +43 -36
- package/target/node/utils.js +1 -1
- package/target/origin.d.ts +4 -0
- package/target/tms_service.d.ts +5 -5
- package/target/tms_service.js +409 -0
- package/target/utils.d.ts +3 -3
- package/target/utils.js +86 -0
- package/target/web/ems_client.js +26 -27
- package/target/web/ems_service.js +7 -8
- package/target/web/file_layer.js +20 -22
- package/target/web/tms_service.js +44 -49
- package/test/__snapshots__/ems_client.test.ts.snap +24 -24
- package/test/ems_client_util.ts +1 -1
- package/.eslintignore +0 -1
- package/.eslintrc +0 -18
package/.buildkite/pipeline.yml
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
yarn test
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file.
|
|
|
3
3
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
5
5
|
|
|
6
|
+
## [8.5.2] - 2024-07-05
|
|
7
|
+
|
|
8
|
+
## Changed
|
|
9
|
+
- Update dependencies #232 #233 #234 #235
|
|
10
|
+
|
|
6
11
|
## [8.5.1] - 2023-11-09
|
|
7
12
|
|
|
8
13
|
### Added
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import eslint from '@eslint/js';
|
|
4
|
+
import tseslint from 'typescript-eslint';
|
|
5
|
+
import globals from 'globals';
|
|
6
|
+
|
|
7
|
+
export default tseslint.config(
|
|
8
|
+
eslint.configs.recommended,
|
|
9
|
+
...tseslint.configs.recommended,
|
|
10
|
+
{
|
|
11
|
+
ignores: ["target","*.config.js"]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
files: ['**/*.{ts,tsx,mts,cts}'],
|
|
15
|
+
rules: {
|
|
16
|
+
'no-undef': 'off',
|
|
17
|
+
'@typescript-eslint/ban-types': 'off'
|
|
18
|
+
},
|
|
19
|
+
"languageOptions": {
|
|
20
|
+
"globals": {
|
|
21
|
+
...globals.node
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
);
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elastic/ems-client",
|
|
3
|
-
"version": "8.5.
|
|
3
|
+
"version": "8.5.2",
|
|
4
4
|
"description": "JavaScript client library for the Elastic Maps Service",
|
|
5
5
|
"main": "target/node/index.js",
|
|
6
6
|
"browser": "target/web/index.js",
|
|
7
7
|
"types": "target/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
|
+
"prepare": "husky",
|
|
9
10
|
"prelint": "tsc --noEmit",
|
|
10
|
-
"lint": "
|
|
11
|
+
"lint": "prettier --check src/* && eslint .",
|
|
11
12
|
"pretest": "yarn lint",
|
|
12
13
|
"test": "jest",
|
|
13
14
|
"build": "tsc --emitDeclarationOnly && yarn build-web && yarn build-node",
|
|
@@ -29,20 +30,14 @@
|
|
|
29
30
|
"url": "https://github.com/elastic/ems-client/issues"
|
|
30
31
|
},
|
|
31
32
|
"homepage": "https://github.com/elastic/ems-client#readme",
|
|
32
|
-
"husky": {
|
|
33
|
-
"hooks": {
|
|
34
|
-
"pre-commit": "yarn test"
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
33
|
"dependencies": {
|
|
38
|
-
"@types/geojson": "^7946.0.
|
|
39
|
-
"@types/
|
|
40
|
-
"@types/topojson-
|
|
41
|
-
"@types/topojson-specification": "^1.0.1",
|
|
34
|
+
"@types/geojson": "^7946.0.14",
|
|
35
|
+
"@types/topojson-client": "^3.1.4",
|
|
36
|
+
"@types/topojson-specification": "^1.0.5",
|
|
42
37
|
"chroma-js": "^2.1.0",
|
|
43
38
|
"lodash": "^4.17.15",
|
|
44
|
-
"lru-cache": "
|
|
45
|
-
"semver": "7.
|
|
39
|
+
"lru-cache": "7.18.3",
|
|
40
|
+
"semver": "7.6.2",
|
|
46
41
|
"topojson-client": "^3.1.0"
|
|
47
42
|
},
|
|
48
43
|
"devDependencies": {
|
|
@@ -51,25 +46,30 @@
|
|
|
51
46
|
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
|
52
47
|
"@babel/preset-env": "^7.5.5",
|
|
53
48
|
"@babel/preset-typescript": "^7.9.0",
|
|
49
|
+
"@eslint/js": "^9.3.0",
|
|
54
50
|
"@types/chroma-js": "^2.1.3",
|
|
55
|
-
"@types/
|
|
51
|
+
"@types/eslint__js": "^8.42.3",
|
|
52
|
+
"@types/jest": "^29.5.12",
|
|
56
53
|
"@types/lodash": "^4.14.150",
|
|
57
|
-
"@types/
|
|
54
|
+
"@types/lru-cache": "^7.10.10",
|
|
55
|
+
"@types/node": "^20.12.13",
|
|
58
56
|
"@types/node-fetch": "^2.5.7",
|
|
59
57
|
"@types/semver": "^7.1.0",
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
61
|
-
"@typescript-eslint/parser": "^
|
|
62
|
-
"babel-jest": "^
|
|
63
|
-
"eslint": "^
|
|
64
|
-
"eslint-config-prettier": "^
|
|
65
|
-
"eslint-plugin-prettier": "^
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "^7.11.0",
|
|
59
|
+
"@typescript-eslint/parser": "^7.11.0",
|
|
60
|
+
"babel-jest": "^29.7.0",
|
|
61
|
+
"eslint": "^9.3.0",
|
|
62
|
+
"eslint-config-prettier": "^9.1.0",
|
|
63
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
64
|
+
"globals": "^15.3.0",
|
|
65
|
+
"husky": "^9.0.11",
|
|
66
|
+
"jest": "^29.7.0",
|
|
67
|
+
"maplibre-gl": "3.1.0",
|
|
68
|
+
"node-fetch": "^2.7.0",
|
|
69
|
+
"prettier": "^3.2.5",
|
|
70
|
+
"ts-jest": "^29.1.4",
|
|
71
|
+
"typescript": "^5.4.5",
|
|
72
|
+
"typescript-eslint": "^7.11.0"
|
|
73
73
|
},
|
|
74
74
|
"engines": {
|
|
75
75
|
"node": ">=18 <=20"
|
package/src/ems_client.ts
CHANGED
|
@@ -290,7 +290,11 @@ export class EMSClient {
|
|
|
290
290
|
if (!response.ok) {
|
|
291
291
|
throw new Error(response.statusText);
|
|
292
292
|
}
|
|
293
|
-
|
|
293
|
+
if (response) {
|
|
294
|
+
return (await response.json()) as Promise<T>;
|
|
295
|
+
} else {
|
|
296
|
+
throw new Error('Response not found');
|
|
297
|
+
}
|
|
294
298
|
} catch (e) {
|
|
295
299
|
if (e instanceof Error) {
|
|
296
300
|
throw e;
|
|
@@ -307,7 +311,7 @@ export class EMSClient {
|
|
|
307
311
|
*/
|
|
308
312
|
addQueryParams(additionalQueryParams: { [key: string]: string }): void {
|
|
309
313
|
for (const key in additionalQueryParams) {
|
|
310
|
-
if (
|
|
314
|
+
if (Object.prototype.hasOwnProperty.call(additionalQueryParams, key)) {
|
|
311
315
|
if (additionalQueryParams[key] !== this._queryParams[key]) {
|
|
312
316
|
//changes detected.
|
|
313
317
|
this._queryParams = _.assign({}, this._queryParams, additionalQueryParams);
|
package/src/tms_service.ts
CHANGED
|
@@ -169,9 +169,8 @@ export class TMSService extends AbstractEmsService {
|
|
|
169
169
|
if (url) {
|
|
170
170
|
const sourceUrl = this._proxyPath + this._getAbsoluteUrl(url);
|
|
171
171
|
const extendedUrl = this._emsClient.extendUrlWithParams(sourceUrl);
|
|
172
|
-
const sourceJson =
|
|
173
|
-
extendedUrl
|
|
174
|
-
);
|
|
172
|
+
const sourceJson =
|
|
173
|
+
await this._emsClient.getManifest<VectorSourceSpecification>(extendedUrl);
|
|
175
174
|
const tiles = sourceJson?.tiles?.map((tileUrl) => {
|
|
176
175
|
const directUrl = this._proxyPath + this._getAbsoluteUrl(tileUrl);
|
|
177
176
|
return this._emsClient.extendUrlWithParams(directUrl);
|
|
@@ -374,16 +373,20 @@ export class TMSService extends AbstractEmsService {
|
|
|
374
373
|
|
|
375
374
|
async getMinZoom(format = 'vector'): Promise<number | undefined> {
|
|
376
375
|
switch (format) {
|
|
377
|
-
case 'vector':
|
|
376
|
+
case 'vector': {
|
|
378
377
|
const { sources } = (await this._getVectorStyleJsonInlined()) || { sources: {} };
|
|
379
378
|
return Math.min(
|
|
380
379
|
...Object.values(sources)
|
|
381
|
-
.map((
|
|
380
|
+
.map((s) => {
|
|
381
|
+
return s && s instanceof Object && 'minzoom' in s ? s['minzoom'] : null;
|
|
382
|
+
})
|
|
382
383
|
.filter((minzoom): minzoom is number => Number.isFinite(minzoom))
|
|
383
384
|
);
|
|
384
|
-
|
|
385
|
+
}
|
|
386
|
+
case 'raster': {
|
|
385
387
|
const { minzoom } = (await this._getRasterStyleJson()) || {};
|
|
386
388
|
return minzoom;
|
|
389
|
+
}
|
|
387
390
|
default:
|
|
388
391
|
return;
|
|
389
392
|
}
|
|
@@ -391,16 +394,20 @@ export class TMSService extends AbstractEmsService {
|
|
|
391
394
|
|
|
392
395
|
async getMaxZoom(format = 'vector'): Promise<number | undefined> {
|
|
393
396
|
switch (format) {
|
|
394
|
-
case 'vector':
|
|
397
|
+
case 'vector': {
|
|
395
398
|
const { sources } = (await this._getVectorStyleJsonInlined()) || { sources: {} };
|
|
396
399
|
return Math.max(
|
|
397
400
|
...Object.values(sources)
|
|
398
|
-
.map((
|
|
401
|
+
.map((s) => {
|
|
402
|
+
return s && s instanceof Object && 'maxzoom' in s ? s['maxzoom'] : null;
|
|
403
|
+
})
|
|
399
404
|
.filter((maxzoom): maxzoom is number => Number.isFinite(maxzoom))
|
|
400
405
|
);
|
|
401
|
-
|
|
406
|
+
}
|
|
407
|
+
case 'raster': {
|
|
402
408
|
const { maxzoom } = (await this._getRasterStyleJson()) || {};
|
|
403
409
|
return maxzoom;
|
|
410
|
+
}
|
|
404
411
|
default:
|
|
405
412
|
return;
|
|
406
413
|
}
|
|
@@ -425,13 +432,12 @@ export class TMSService extends AbstractEmsService {
|
|
|
425
432
|
vectorFormats = this._getFormats(formatType, this._emsClient.getDefaultLocale());
|
|
426
433
|
}
|
|
427
434
|
if (!vectorFormats.length) {
|
|
428
|
-
// eslint-disable-next-line max-len
|
|
429
435
|
throw new Error(
|
|
430
436
|
`Cannot find ${formatType} tile layer for locale ${this._emsClient.getLocale()} or ${this._emsClient.getDefaultLocale()}`
|
|
431
437
|
);
|
|
432
438
|
}
|
|
433
439
|
const defaultStyle = vectorFormats[0];
|
|
434
|
-
if (defaultStyle &&
|
|
440
|
+
if (defaultStyle && Object.prototype.hasOwnProperty.call(defaultStyle, 'url')) {
|
|
435
441
|
return defaultStyle.url;
|
|
436
442
|
}
|
|
437
443
|
}
|
|
@@ -445,7 +451,7 @@ export class TMSService extends AbstractEmsService {
|
|
|
445
451
|
private async _getSpriteSheetRootPath(): Promise<string> {
|
|
446
452
|
const vectorStyleJson = await this._getVectorStyleJsonRaw();
|
|
447
453
|
if (vectorStyleJson?.sprite) {
|
|
448
|
-
return this._proxyPath + this._getAbsoluteUrl(vectorStyleJson.sprite);
|
|
454
|
+
return this._proxyPath + this._getAbsoluteUrl(vectorStyleJson.sprite.toString());
|
|
449
455
|
} else {
|
|
450
456
|
return '';
|
|
451
457
|
}
|
package/target/ems_client.d.ts
CHANGED
|
@@ -2,10 +2,10 @@ import { TMSService } from './tms_service';
|
|
|
2
2
|
import { EMSFormatType, FileLayer } from './file_layer';
|
|
3
3
|
import { FeatureCollection } from 'geojson';
|
|
4
4
|
export declare const LATEST_API_URL_PATH = "latest";
|
|
5
|
-
|
|
5
|
+
type LocalizedStrings = {
|
|
6
6
|
[key: string]: string;
|
|
7
7
|
};
|
|
8
|
-
|
|
8
|
+
type BaseClientConfig = {
|
|
9
9
|
appName?: string;
|
|
10
10
|
manifestServiceUrl?: string;
|
|
11
11
|
tileApiUrl: string;
|
|
@@ -18,35 +18,35 @@ declare type BaseClientConfig = {
|
|
|
18
18
|
proxyPath?: string;
|
|
19
19
|
cacheSize?: number;
|
|
20
20
|
};
|
|
21
|
-
|
|
21
|
+
type DeprecatedClientConfig = BaseClientConfig & {
|
|
22
22
|
kbnVersion: string;
|
|
23
23
|
};
|
|
24
|
-
|
|
24
|
+
type ClientConfig = BaseClientConfig & {
|
|
25
25
|
appVersion: string;
|
|
26
26
|
};
|
|
27
|
-
|
|
27
|
+
type EmsCatalogService = {
|
|
28
28
|
id?: string;
|
|
29
29
|
name?: string;
|
|
30
30
|
manifest: string;
|
|
31
31
|
type: string;
|
|
32
32
|
};
|
|
33
|
-
|
|
33
|
+
type EmsCatalogManifest = {
|
|
34
34
|
version?: string;
|
|
35
35
|
services: EmsCatalogService[];
|
|
36
36
|
};
|
|
37
|
-
|
|
37
|
+
type EmsTmsCatalog = {
|
|
38
38
|
version?: string;
|
|
39
39
|
services: TMSServiceConfig[];
|
|
40
40
|
};
|
|
41
|
-
export
|
|
41
|
+
export type EmsTmsFormat = {
|
|
42
42
|
locale: string;
|
|
43
43
|
format: string;
|
|
44
44
|
url: string;
|
|
45
45
|
};
|
|
46
|
-
export
|
|
46
|
+
export type BaseEmsServiceConfig = {
|
|
47
47
|
attribution: EmsLayerAttribution[];
|
|
48
48
|
};
|
|
49
|
-
export
|
|
49
|
+
export type FileLayerConfig = BaseEmsServiceConfig & {
|
|
50
50
|
layer_id: string;
|
|
51
51
|
created_at: string;
|
|
52
52
|
formats: (EmsFileLayerFormatGeoJson | EmsFileLayerFormatTopoJson)[];
|
|
@@ -54,7 +54,7 @@ export declare type FileLayerConfig = BaseEmsServiceConfig & {
|
|
|
54
54
|
legacy_ids: string[];
|
|
55
55
|
layer_name: LocalizedStrings;
|
|
56
56
|
};
|
|
57
|
-
export
|
|
57
|
+
export type FileLayerField = {
|
|
58
58
|
type: string;
|
|
59
59
|
id: string;
|
|
60
60
|
label: LocalizedStrings;
|
|
@@ -62,27 +62,27 @@ export declare type FileLayerField = {
|
|
|
62
62
|
regex?: string;
|
|
63
63
|
alias?: string[];
|
|
64
64
|
};
|
|
65
|
-
export
|
|
65
|
+
export type TMSServiceConfig = BaseEmsServiceConfig & {
|
|
66
66
|
id: string;
|
|
67
67
|
name: {
|
|
68
68
|
en: string;
|
|
69
69
|
};
|
|
70
70
|
formats: EmsTmsFormat[];
|
|
71
71
|
};
|
|
72
|
-
|
|
72
|
+
type EmsFileCatalog = {
|
|
73
73
|
version?: string;
|
|
74
74
|
layers: FileLayerConfig[];
|
|
75
75
|
};
|
|
76
|
-
export
|
|
76
|
+
export type EmsLayerAttribution = {
|
|
77
77
|
label: LocalizedStrings;
|
|
78
78
|
url: LocalizedStrings;
|
|
79
79
|
};
|
|
80
|
-
export
|
|
80
|
+
export type EmsFileLayerFormatGeoJson = {
|
|
81
81
|
type: EMSFormatType.geojson;
|
|
82
82
|
url: string;
|
|
83
83
|
legacy_default: boolean;
|
|
84
84
|
};
|
|
85
|
-
export
|
|
85
|
+
export type EmsFileLayerFormatTopoJson = {
|
|
86
86
|
type: EMSFormatType.topojson;
|
|
87
87
|
url: string;
|
|
88
88
|
legacy_default: boolean;
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.EMSClient = exports.LATEST_API_URL_PATH = void 0;
|
|
16
|
+
/*
|
|
17
|
+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
18
|
+
* or more contributor license agreements. Licensed under the Elastic License
|
|
19
|
+
* 2.0; you may not use this file except in compliance with the Elastic License
|
|
20
|
+
* 2.0.
|
|
21
|
+
*/
|
|
22
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
23
|
+
const tms_service_1 = require("./tms_service");
|
|
24
|
+
const file_layer_1 = require("./file_layer");
|
|
25
|
+
const coerce_1 = __importDefault(require("semver/functions/coerce"));
|
|
26
|
+
const valid_1 = __importDefault(require("semver/functions/valid"));
|
|
27
|
+
const major_1 = __importDefault(require("semver/functions/major"));
|
|
28
|
+
const minor_1 = __importDefault(require("semver/functions/minor"));
|
|
29
|
+
const url_1 = require("url");
|
|
30
|
+
const utils_1 = require("./utils");
|
|
31
|
+
const lru_cache_1 = __importDefault(require("lru-cache"));
|
|
32
|
+
const REST_API_REGEX = /\d{4}-\d{2}-\d{2}/;
|
|
33
|
+
exports.LATEST_API_URL_PATH = 'latest';
|
|
34
|
+
/**
|
|
35
|
+
* plugins cannot have upstream dependencies on core/*-kibana.
|
|
36
|
+
* Work-around by copy-pasting modifyUrl routine here.
|
|
37
|
+
* @param url
|
|
38
|
+
* @param block
|
|
39
|
+
*/
|
|
40
|
+
function modifyUrlLocal(url, block) {
|
|
41
|
+
const parsed = (0, url_1.parse)(url, true);
|
|
42
|
+
// copy over the most specific version of each
|
|
43
|
+
// property. By default, the parsed url includes
|
|
44
|
+
// several conflicting properties (like path and
|
|
45
|
+
// pathname + search, or search and query) and keeping
|
|
46
|
+
// track of which property is actually used when they
|
|
47
|
+
// are formatted is harder than necessary
|
|
48
|
+
const meaningfulParts = {
|
|
49
|
+
protocol: parsed.protocol,
|
|
50
|
+
slashes: parsed.slashes,
|
|
51
|
+
auth: parsed.auth,
|
|
52
|
+
hostname: parsed.hostname,
|
|
53
|
+
port: parsed.port,
|
|
54
|
+
pathname: parsed.pathname,
|
|
55
|
+
query: parsed.query || {},
|
|
56
|
+
hash: parsed.hash,
|
|
57
|
+
};
|
|
58
|
+
// the block modifies the meaningfulParts object, or returns a new one
|
|
59
|
+
const modifiedParts = block(meaningfulParts) || meaningfulParts;
|
|
60
|
+
// format the modified/replaced meaningfulParts back into a url
|
|
61
|
+
return (0, url_1.format)({
|
|
62
|
+
protocol: modifiedParts.protocol,
|
|
63
|
+
slashes: modifiedParts.slashes,
|
|
64
|
+
auth: modifiedParts.auth,
|
|
65
|
+
hostname: modifiedParts.hostname,
|
|
66
|
+
port: modifiedParts.port,
|
|
67
|
+
pathname: modifiedParts.pathname,
|
|
68
|
+
query: modifiedParts.query,
|
|
69
|
+
hash: modifiedParts.hash,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const extendUrl = (url, props) => modifyUrlLocal(url, (parsed) => lodash_1.default.merge(parsed, props));
|
|
73
|
+
/**
|
|
74
|
+
* Unescape a url template that was escaped by encodeURI() so leaflet
|
|
75
|
+
* will be able to correctly locate the variables in the template
|
|
76
|
+
* @param {String} url
|
|
77
|
+
* @return {String}
|
|
78
|
+
*/
|
|
79
|
+
const unescapeTemplateVars = (url) => {
|
|
80
|
+
const ENCODED_TEMPLATE_VARS_RE = /%7B(\w+?)%7D/g;
|
|
81
|
+
return url.replace(ENCODED_TEMPLATE_VARS_RE, (total, varName) => `{${varName}}`);
|
|
82
|
+
};
|
|
83
|
+
//this is not the default locale from Kibana, but the default locale supported by the Elastic Maps Service
|
|
84
|
+
const DEFAULT_LANGUAGE = 'en';
|
|
85
|
+
class EMSClient {
|
|
86
|
+
constructor(config) {
|
|
87
|
+
this.EMS_LOAD_TIMEOUT = 32000;
|
|
88
|
+
this._isRestApi = false;
|
|
89
|
+
// Remove kbnVersion in 8.0
|
|
90
|
+
if ('kbnVersion' in config) {
|
|
91
|
+
console.warn('The "kbnVersion" parameter for ems-client is deprecated. Please use "appVersion" instead.');
|
|
92
|
+
this._appVersion = config.kbnVersion;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
this._appVersion = config.appVersion;
|
|
96
|
+
}
|
|
97
|
+
this._queryParams = {
|
|
98
|
+
elastic_tile_service_tos: 'agree',
|
|
99
|
+
my_app_name: config.appName || 'kibana',
|
|
100
|
+
my_app_version: this._appVersion,
|
|
101
|
+
};
|
|
102
|
+
this._sanitizer = config.htmlSanitizer ? config.htmlSanitizer : (x) => x;
|
|
103
|
+
this._tileApiUrl = config.tileApiUrl;
|
|
104
|
+
this._fileApiUrl = config.fileApiUrl;
|
|
105
|
+
this._emsVersion = this._getEmsVersion(config.emsVersion);
|
|
106
|
+
this._isRestApi = this._emsVersion == config.emsVersion;
|
|
107
|
+
this._emsLandingPageUrl = config.landingPageUrl || '';
|
|
108
|
+
this._language = config.language || DEFAULT_LANGUAGE;
|
|
109
|
+
this._fetchFunction = config.fetchFunction;
|
|
110
|
+
this._proxyPath = config.proxyPath || '';
|
|
111
|
+
this._cache = new lru_cache_1.default({
|
|
112
|
+
max: config.cacheSize || 10,
|
|
113
|
+
});
|
|
114
|
+
this._invalidateSettings();
|
|
115
|
+
}
|
|
116
|
+
getDefaultLocale() {
|
|
117
|
+
return DEFAULT_LANGUAGE;
|
|
118
|
+
}
|
|
119
|
+
getLocale() {
|
|
120
|
+
return this._language;
|
|
121
|
+
}
|
|
122
|
+
getValueInLanguage(i18nObject) {
|
|
123
|
+
if (!i18nObject) {
|
|
124
|
+
return '';
|
|
125
|
+
}
|
|
126
|
+
return i18nObject[this._language] ? i18nObject[this._language] : i18nObject[DEFAULT_LANGUAGE];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* this internal method is overridden by the tests to simulate custom manifest.
|
|
130
|
+
*/
|
|
131
|
+
getManifest(endpointUrl) {
|
|
132
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
133
|
+
try {
|
|
134
|
+
const url = extendUrl(endpointUrl, { query: this._queryParams });
|
|
135
|
+
const response = yield this._fetchWithTimeout(url);
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
throw new Error(response.statusText);
|
|
138
|
+
}
|
|
139
|
+
if (response) {
|
|
140
|
+
return (yield response.json());
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
throw new Error('Response not found');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
if (e instanceof Error) {
|
|
148
|
+
throw e;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
throw new Error('Unknown error');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Add optional query-parameters to all requests
|
|
158
|
+
*
|
|
159
|
+
* @param additionalQueryParams
|
|
160
|
+
*/
|
|
161
|
+
addQueryParams(additionalQueryParams) {
|
|
162
|
+
for (const key in additionalQueryParams) {
|
|
163
|
+
if (Object.prototype.hasOwnProperty.call(additionalQueryParams, key)) {
|
|
164
|
+
if (additionalQueryParams[key] !== this._queryParams[key]) {
|
|
165
|
+
//changes detected.
|
|
166
|
+
this._queryParams = lodash_1.default.assign({}, this._queryParams, additionalQueryParams);
|
|
167
|
+
this._invalidateSettings();
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
getMainManifest() {
|
|
174
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
175
|
+
return yield this._getMainCatalog();
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
getDefaultFileManifest() {
|
|
179
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
180
|
+
return yield this._getDefaultFileCatalog();
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
getDefaultTMSManifest() {
|
|
184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
185
|
+
return yield this._getDefaultTMSCatalog();
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
getFileLayers() {
|
|
189
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
190
|
+
return yield this._loadFileLayers();
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
getTMSServices() {
|
|
194
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
195
|
+
return yield this._loadTMSServices();
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
cacheGeoJson(layerId, geoJson) {
|
|
199
|
+
this._cache.set(layerId, geoJson);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
getCachedGeoJson(layerId) {
|
|
203
|
+
return this._cache.get(layerId);
|
|
204
|
+
}
|
|
205
|
+
getEmsVersion() {
|
|
206
|
+
return this._emsVersion;
|
|
207
|
+
}
|
|
208
|
+
getTileApiUrl() {
|
|
209
|
+
return this._tileApiUrl;
|
|
210
|
+
}
|
|
211
|
+
getFileApiUrl() {
|
|
212
|
+
return this._fileApiUrl;
|
|
213
|
+
}
|
|
214
|
+
getLandingPageUrl() {
|
|
215
|
+
return this._emsLandingPageUrl;
|
|
216
|
+
}
|
|
217
|
+
sanitizeHtml(html) {
|
|
218
|
+
return this._sanitizer(html);
|
|
219
|
+
}
|
|
220
|
+
extendUrlWithParams(url) {
|
|
221
|
+
return unescapeTemplateVars(extendUrl(url, {
|
|
222
|
+
query: this._queryParams,
|
|
223
|
+
}));
|
|
224
|
+
}
|
|
225
|
+
findFileLayerById(id) {
|
|
226
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
227
|
+
const fileLayers = yield this.getFileLayers();
|
|
228
|
+
for (let i = 0; i < fileLayers.length; i++) {
|
|
229
|
+
if (fileLayers[i].hasId(id)) {
|
|
230
|
+
return fileLayers[i];
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
findTMSServiceById(id) {
|
|
236
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
237
|
+
const tmsServices = yield this.getTMSServices();
|
|
238
|
+
for (let i = 0; i < tmsServices.length; i++) {
|
|
239
|
+
if (tmsServices[i].hasId(id)) {
|
|
240
|
+
return tmsServices[i];
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
_getEmsVersion(version) {
|
|
246
|
+
if (version === null || version === void 0 ? void 0 : version.match(REST_API_REGEX)) {
|
|
247
|
+
return version;
|
|
248
|
+
}
|
|
249
|
+
const semverVersion = (0, valid_1.default)((0, coerce_1.default)(version));
|
|
250
|
+
if (semverVersion) {
|
|
251
|
+
return `v${(0, major_1.default)(semverVersion)}.${(0, minor_1.default)(semverVersion)}`;
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
throw new Error(`Invalid version: ${version}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
_fetchWithTimeout(url) {
|
|
258
|
+
return new Promise((resolve, reject) => {
|
|
259
|
+
const timer = setTimeout(() => reject(new Error(`Request to ${url} timed out`)), this.EMS_LOAD_TIMEOUT);
|
|
260
|
+
this._fetchFunction(url).then((response) => {
|
|
261
|
+
clearTimeout(timer);
|
|
262
|
+
resolve(response);
|
|
263
|
+
}, (err) => {
|
|
264
|
+
clearTimeout(timer);
|
|
265
|
+
reject(err);
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
_invalidateSettings() {
|
|
270
|
+
this._cache.reset();
|
|
271
|
+
this._getMainCatalog = lodash_1.default.once(() => __awaiter(this, void 0, void 0, function* () {
|
|
272
|
+
const services = [];
|
|
273
|
+
if (this._tileApiUrl) {
|
|
274
|
+
const version = this._isRestApi ? exports.LATEST_API_URL_PATH : this._emsVersion;
|
|
275
|
+
services.push({
|
|
276
|
+
type: 'tms',
|
|
277
|
+
manifest: (0, utils_1.toAbsoluteUrl)(this._tileApiUrl, `${version}/manifest`),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
if (this._fileApiUrl) {
|
|
281
|
+
const version = this._isRestApi ? exports.LATEST_API_URL_PATH : this._emsVersion;
|
|
282
|
+
services.push({
|
|
283
|
+
type: 'file',
|
|
284
|
+
manifest: (0, utils_1.toAbsoluteUrl)(this._fileApiUrl, `${version}/manifest`),
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
return { services: services };
|
|
288
|
+
}));
|
|
289
|
+
this._getDefaultTMSCatalog = lodash_1.default.once(() => __awaiter(this, void 0, void 0, function* () {
|
|
290
|
+
const catalogue = yield this._getMainCatalog();
|
|
291
|
+
const firstService = catalogue.services.find((service) => service.type === 'tms');
|
|
292
|
+
if (!firstService) {
|
|
293
|
+
return { services: [] };
|
|
294
|
+
}
|
|
295
|
+
const url = this._proxyPath + firstService.manifest;
|
|
296
|
+
return yield this.getManifest(url);
|
|
297
|
+
}));
|
|
298
|
+
this._getDefaultFileCatalog = lodash_1.default.once(() => __awaiter(this, void 0, void 0, function* () {
|
|
299
|
+
const catalogue = yield this._getMainCatalog();
|
|
300
|
+
const firstService = catalogue.services.find((service) => service.type === 'file');
|
|
301
|
+
if (!firstService) {
|
|
302
|
+
return { layers: [] };
|
|
303
|
+
}
|
|
304
|
+
const url = this._proxyPath + firstService.manifest;
|
|
305
|
+
return yield this.getManifest(url);
|
|
306
|
+
}));
|
|
307
|
+
//Cache the actual instances of TMSService as these in turn cache sub-manifests for the style-files
|
|
308
|
+
this._loadTMSServices = lodash_1.default.once(() => __awaiter(this, void 0, void 0, function* () {
|
|
309
|
+
const tmsManifest = yield this._getDefaultTMSCatalog();
|
|
310
|
+
return tmsManifest.services.map((serviceConfig) => new tms_service_1.TMSService(serviceConfig, this, this._proxyPath));
|
|
311
|
+
}));
|
|
312
|
+
this._loadFileLayers = lodash_1.default.once(() => __awaiter(this, void 0, void 0, function* () {
|
|
313
|
+
const fileManifest = yield this._getDefaultFileCatalog();
|
|
314
|
+
return fileManifest.layers.map((layerConfig) => new file_layer_1.FileLayer(layerConfig, this, this._proxyPath));
|
|
315
|
+
}));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
exports.EMSClient = EMSClient;
|