@nextgis/geocoder 3.0.0-alpha.3 → 3.0.0-alpha.5

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.
@@ -1,4 +1,4 @@
1
- /** Bundle of @nextgis/geocoder; version: 3.0.0-alpha.3; author: NextGIS */
1
+ /** Bundle of @nextgis/geocoder; version: 3.0.0-alpha.5; author: NextGIS */
2
2
  var Geocoder = (function (exports) {
3
3
  'use strict';
4
4
 
@@ -107,28 +107,28 @@ var Geocoder = (function (exports) {
107
107
  }
108
108
  }
109
109
 
110
- var __defProp$d = Object.defineProperty;
111
- var __defProps$3 = Object.defineProperties;
112
- var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
113
- var __getOwnPropSymbols$6 = Object.getOwnPropertySymbols;
114
- var __hasOwnProp$6 = Object.prototype.hasOwnProperty;
115
- var __propIsEnum$6 = Object.prototype.propertyIsEnumerable;
110
+ var __defProp$h = Object.defineProperty;
111
+ var __defProps$4 = Object.defineProperties;
112
+ var __getOwnPropDescs$4 = Object.getOwnPropertyDescriptors;
113
+ var __getOwnPropSymbols$8 = Object.getOwnPropertySymbols;
114
+ var __hasOwnProp$8 = Object.prototype.hasOwnProperty;
115
+ var __propIsEnum$8 = Object.prototype.propertyIsEnumerable;
116
116
  var __knownSymbol$2 = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
117
- var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
118
- var __spreadValues$6 = (a, b) => {
117
+ var __defNormalProp$h = (obj, key, value) => key in obj ? __defProp$h(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
118
+ var __spreadValues$8 = (a, b) => {
119
119
  for (var prop in b || (b = {}))
120
- if (__hasOwnProp$6.call(b, prop))
121
- __defNormalProp$d(a, prop, b[prop]);
122
- if (__getOwnPropSymbols$6)
123
- for (var prop of __getOwnPropSymbols$6(b)) {
124
- if (__propIsEnum$6.call(b, prop))
125
- __defNormalProp$d(a, prop, b[prop]);
120
+ if (__hasOwnProp$8.call(b, prop))
121
+ __defNormalProp$h(a, prop, b[prop]);
122
+ if (__getOwnPropSymbols$8)
123
+ for (var prop of __getOwnPropSymbols$8(b)) {
124
+ if (__propIsEnum$8.call(b, prop))
125
+ __defNormalProp$h(a, prop, b[prop]);
126
126
  }
127
127
  return a;
128
128
  };
129
- var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
130
- var __publicField$a = (obj, key, value) => __defNormalProp$d(obj, key + "" , value);
131
- var __async$5 = (__this, __arguments, generator) => {
129
+ var __spreadProps$4 = (a, b) => __defProps$4(a, __getOwnPropDescs$4(b));
130
+ var __publicField$c = (obj, key, value) => __defNormalProp$h(obj, key + "" , value);
131
+ var __async$7 = (__this, __arguments, generator) => {
132
132
  return new Promise((resolve, reject) => {
133
133
  var fulfilled = (value) => {
134
134
  try {
@@ -168,7 +168,7 @@ var Geocoder = (function (exports) {
168
168
  class Geocoder extends BaseGeocoder {
169
169
  constructor(options) {
170
170
  super(options);
171
- __publicField$a(this, "providers", []);
171
+ __publicField$c(this, "providers", []);
172
172
  if (options && options.providers) {
173
173
  this.providers = options.providers;
174
174
  }
@@ -192,7 +192,7 @@ var Geocoder = (function (exports) {
192
192
  for (var iter = __forAwait(results), more, temp, error; more = !(temp = yield new __await$2(iter.next())).done; more = false) {
193
193
  const r = temp.value;
194
194
  allProvidersFailed = false;
195
- yield __spreadProps$3(__spreadValues$6({}, r), { provider, _id: ID$1++ });
195
+ yield __spreadProps$4(__spreadValues$8({}, r), { provider, _id: ID$1++ });
196
196
  }
197
197
  } catch (temp) {
198
198
  error = [temp];
@@ -235,7 +235,7 @@ var Geocoder = (function (exports) {
235
235
  try {
236
236
  for (var iter = __forAwait(results), more, temp, error; more = !(temp = yield new __await$2(iter.next())).done; more = false) {
237
237
  const r = temp.value;
238
- yield __spreadProps$3(__spreadValues$6({}, r), { provider, _id: ID$1++ });
238
+ yield __spreadProps$4(__spreadValues$8({}, r), { provider, _id: ID$1++ });
239
239
  }
240
240
  } catch (temp) {
241
241
  error = [temp];
@@ -259,7 +259,7 @@ var Geocoder = (function (exports) {
259
259
  * @returns A promise that resolves to the first reverse geocoding result, or undefined if no results are found.
260
260
  */
261
261
  reverseGeocodeFirstResult(coordinates) {
262
- return __async$5(this, null, function* () {
262
+ return __async$7(this, null, function* () {
263
263
  for (const provider of this.providers) {
264
264
  if (typeof provider.reverse === "function") {
265
265
  try {
@@ -288,9 +288,9 @@ var Geocoder = (function (exports) {
288
288
  }
289
289
  }
290
290
 
291
- var __defProp$c = Object.defineProperty;
292
- var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
293
- var __publicField$9 = (obj, key, value) => __defNormalProp$c(obj, typeof key !== "symbol" ? key + "" : key, value);
291
+ var __defProp$g = Object.defineProperty;
292
+ var __defNormalProp$g = (obj, key, value) => key in obj ? __defProp$g(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
293
+ var __publicField$b = (obj, key, value) => __defNormalProp$g(obj, typeof key !== "symbol" ? key + "" : key, value);
294
294
  class BaseProvider extends BaseGeocoder {
295
295
  constructor() {
296
296
  super(...arguments);
@@ -298,12 +298,12 @@ var Geocoder = (function (exports) {
298
298
  * URL endpoint for the search service.
299
299
  * This is where queries will be sent to obtain search results.
300
300
  */
301
- __publicField$9(this, "searchUrl");
301
+ __publicField$b(this, "searchUrl");
302
302
  /**
303
303
  * Label to represent the provider.
304
304
  * Useful for user interfaces to display the source of search results.
305
305
  */
306
- __publicField$9(this, "label");
306
+ __publicField$b(this, "label");
307
307
  }
308
308
  }
309
309
 
@@ -337,7 +337,7 @@ var Geocoder = (function (exports) {
337
337
  this.domain = null;
338
338
  if (EventEmitter.usingDomains) {
339
339
  // if there is an active domain, then attach to it.
340
- if (domain.active ) ;
340
+ if (domain.active) ;
341
341
  }
342
342
 
343
343
  if (!this._events || this._events === Object.getPrototypeOf(this)._events) {
@@ -779,12 +779,12 @@ var Geocoder = (function (exports) {
779
779
  return ret;
780
780
  }
781
781
 
782
- var __defProp$b = Object.defineProperty;
783
- var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
784
- var __publicField$8 = (obj, key, value) => __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
782
+ var __defProp$f = Object.defineProperty;
783
+ var __defNormalProp$f = (obj, key, value) => key in obj ? __defProp$f(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
784
+ var __publicField$a = (obj, key, value) => __defNormalProp$f(obj, typeof key !== "symbol" ? key + "" : key, value);
785
785
  const _Cache = class _Cache {
786
786
  constructor(options = {}) {
787
- __publicField$8(this, "cache", []);
787
+ __publicField$a(this, "cache", []);
788
788
  var _a;
789
789
  const namespace = (_a = options.namespace) != null ? _a : "default";
790
790
  if (_Cache.instance[namespace]) {
@@ -890,12 +890,12 @@ var Geocoder = (function (exports) {
890
890
  return objectDeepEqual(itemProps || {}, objectRemoveEmpty(props));
891
891
  }
892
892
  };
893
- __publicField$8(_Cache, "instance", {});
893
+ __publicField$a(_Cache, "instance", {});
894
894
  let Cache = _Cache;
895
895
 
896
896
  var pkg = {
897
897
  name: "@nextgis/ngw-connector",
898
- version: "3.0.0-alpha.3",
898
+ version: "3.0.0-alpha.5",
899
899
  _priority: 12,
900
900
  description: "A lightweight HTTP client optimized for use with NextGIS Web API",
901
901
  main: "index.js",
@@ -904,15 +904,15 @@ var Geocoder = (function (exports) {
904
904
  jsdelivr: "lib/ngw-connector.global.prod.js",
905
905
  types: "lib/index.d.ts",
906
906
  dependencies: {
907
- "@nextgis/cache": "^3.0.0-alpha.3",
908
- "@nextgis/cancelable-promise": "^3.0.0-alpha.3",
909
- "@nextgis/utils": "^3.0.0-alpha.3",
907
+ "@nextgis/cache": "^3.0.0-alpha.5",
908
+ "@nextgis/cancelable-promise": "^3.0.0-alpha.5",
909
+ "@nextgis/utils": "^3.0.0-alpha.5",
910
910
  "@types/events": "^3.0.0",
911
911
  events: "*",
912
912
  "form-data": "^4.0.0"
913
913
  },
914
914
  devDependencies: {
915
- "@nextgis/build-tools": "^3.0.0-alpha.3"
915
+ "@nextgis/build-tools": "^3.0.0-alpha.5"
916
916
  },
917
917
  scripts: {
918
918
  clean: "rimraf ./lib",
@@ -946,87 +946,179 @@ var Geocoder = (function (exports) {
946
946
  type: "git",
947
947
  url: "git://github.com/nextgis/nextgis_frontend.git"
948
948
  },
949
+ engines: {
950
+ node: ">=18.20.4"
951
+ },
949
952
  gitHead: "edc68033f914f6c95c4125b9738bba6d36e990b4"
950
953
  };
951
954
 
952
- var __defProp$a = Object.defineProperty;
953
- var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
954
- var __publicField$7 = (obj, key, value) => __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
955
+ const CONNECTORS = [];
956
+ function addConnector(connector) {
957
+ CONNECTORS.push(connector);
958
+ }
959
+ function findConnector(options) {
960
+ return CONNECTORS.find((x) => {
961
+ if (x.options.baseUrl === options.baseUrl) {
962
+ if (options.auth) {
963
+ if (x.options.auth) {
964
+ return objectDeepEqual(x.options.auth, options.auth);
965
+ }
966
+ } else {
967
+ return true;
968
+ }
969
+ }
970
+ });
971
+ }
972
+ function removeConnector(connector) {
973
+ const index = CONNECTORS.indexOf(connector);
974
+ if (index !== -1) {
975
+ CONNECTORS.splice(index, 1);
976
+ }
977
+ }
978
+
979
+ class AbortError extends Error {
980
+ constructor(message = "AbortError") {
981
+ super(message);
982
+ this.name = "AbortError";
983
+ }
984
+ }
985
+
986
+ var __defProp$e = Object.defineProperty;
987
+ var __defNormalProp$e = (obj, key, value) => key in obj ? __defProp$e(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
988
+ var __publicField$9 = (obj, key, value) => __defNormalProp$e(obj, typeof key !== "symbol" ? key + "" : key, value);
955
989
  class NgwError extends Error {
956
990
  constructor(er) {
957
991
  super();
958
- __publicField$7(this, "name", "NgwError");
959
- __publicField$7(this, "title");
960
- __publicField$7(this, "message");
961
- __publicField$7(this, "detail");
962
- __publicField$7(this, "exception");
963
- __publicField$7(this, "status_code");
964
- __publicField$7(this, "data");
965
- __publicField$7(this, "guru_meditation");
992
+ __publicField$9(this, "name", "NgwError");
993
+ __publicField$9(this, "title");
994
+ __publicField$9(this, "message");
995
+ __publicField$9(this, "detail");
996
+ __publicField$9(this, "exception");
997
+ __publicField$9(this, "status_code");
998
+ __publicField$9(this, "data");
999
+ __publicField$9(this, "guru_meditation");
966
1000
  Object.assign(this, er);
967
1001
  Object.setPrototypeOf(this, NgwError.prototype);
968
1002
  }
969
1003
  }
970
1004
 
971
- var __defProp$9 = Object.defineProperty;
972
- var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
973
- var __publicField$6 = (obj, key, value) => __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
1005
+ var __defProp$d = Object.defineProperty;
1006
+ var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1007
+ var __publicField$8 = (obj, key, value) => __defNormalProp$d(obj, typeof key !== "symbol" ? key + "" : key, value);
1008
+ class InsufficientPermissionsError extends NgwError {
1009
+ constructor(obj) {
1010
+ super(obj);
1011
+ __publicField$8(this, "name", "InsufficientPermissionsError");
1012
+ __publicField$8(this, "exception", "nextgisweb.core.exception.InsufficientPermissions");
1013
+ Object.setPrototypeOf(this, InsufficientPermissionsError.prototype);
1014
+ }
1015
+ }
1016
+
1017
+ var __defProp$c = Object.defineProperty;
1018
+ var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1019
+ var __publicField$7 = (obj, key, value) => __defNormalProp$c(obj, typeof key !== "symbol" ? key + "" : key, value);
974
1020
  class ResourceNotFoundError extends NgwError {
975
1021
  constructor(obj) {
976
1022
  super(obj);
977
- __publicField$6(this, "name", "ResourceNotFoundError");
978
- __publicField$6(this, "exception", "nextgisweb.resource.exception.ResourceNotFound");
1023
+ __publicField$7(this, "name", "ResourceNotFoundError");
1024
+ __publicField$7(this, "exception", "nextgisweb.resource.exception.ResourceNotFound");
979
1025
  Object.setPrototypeOf(this, ResourceNotFoundError.prototype);
980
1026
  }
981
1027
  }
982
1028
 
983
- function isObject(val) {
984
- return Object.prototype.toString.call(val) === "[object Object]";
1029
+ var __defProp$b = Object.defineProperty;
1030
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1031
+ var __publicField$6 = (obj, key, value) => __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
1032
+ class BaseAPIError extends Error {
1033
+ constructor(message) {
1034
+ super(message || "Something went wrong.");
1035
+ __publicField$6(this, "title");
1036
+ this.name = "BaseAPIError";
1037
+ this.title = "Unknown API error";
1038
+ if (Error.captureStackTrace) {
1039
+ Error.captureStackTrace(this, BaseAPIError);
1040
+ }
1041
+ }
985
1042
  }
986
-
987
- function resourceCompare(res1, res2) {
988
- return objectDeepEqual(res1, res2);
1043
+ class NetworksResponseError extends BaseAPIError {
1044
+ // prettier-ignore
1045
+ constructor(message) {
1046
+ super(message || "There is no response from the server or problem connecting to server.");
1047
+ __publicField$6(this, "detail");
1048
+ this.title = "Network error";
1049
+ this.detail = "Check network connectivity and try again later.";
1050
+ }
989
1051
  }
990
-
991
- const exclude = ["description"];
992
- function resourceToQuery(resource, prefix = "") {
993
- prefix = prefix ? prefix + "__" : "";
994
- const query = {};
995
- for (const [key, value] of Object.entries(resource)) {
996
- if (exclude.indexOf(key) === -1) {
997
- if (isObject(value)) {
998
- if (key === "owner_user") {
999
- const children = resourceToQuery(value, key);
1000
- Object.assign(query, children);
1001
- } else if (key === "parent" && "id" in value) {
1002
- query.parent_id = value.id;
1003
- }
1004
- } else if (defined(value)) {
1005
- query[prefix + key] = value;
1006
- }
1052
+ class InvalidResponseError extends BaseAPIError {
1053
+ constructor(message) {
1054
+ super(message || "Something went wrong.");
1055
+ this.title = "Unexpected server response";
1056
+ }
1057
+ }
1058
+ class ServerResponseError extends BaseAPIError {
1059
+ constructor(data) {
1060
+ super(data.message);
1061
+ __publicField$6(this, "detail");
1062
+ __publicField$6(this, "data");
1063
+ this.title = data.title || this.title;
1064
+ this.detail = data.detail || null;
1065
+ this.data = data;
1066
+ }
1067
+ }
1068
+ class LunkwillError extends Error {
1069
+ // prettier-ignore
1070
+ constructor(message, data = {}) {
1071
+ super(message || "Unexpected error while processing long-running request.");
1072
+ __publicField$6(this, "title");
1073
+ __publicField$6(this, "data");
1074
+ this.name = "LunkwillError";
1075
+ this.title = "Long-running request error";
1076
+ this.data = data;
1077
+ if (Error.captureStackTrace) {
1078
+ Error.captureStackTrace(this, LunkwillError);
1007
1079
  }
1008
1080
  }
1009
- return query;
1081
+ }
1082
+ class LunkwillRequestCancelled extends LunkwillError {
1083
+ constructor(data) {
1084
+ super("Long-running request was cancelled.", data);
1085
+ }
1086
+ }
1087
+ class LunkwillRequestFailed extends LunkwillError {
1088
+ constructor(data) {
1089
+ super(void 0, data);
1090
+ }
1010
1091
  }
1011
1092
 
1012
- var __defProp$8 = Object.defineProperty;
1013
- var __getOwnPropSymbols$5 = Object.getOwnPropertySymbols;
1014
- var __hasOwnProp$5 = Object.prototype.hasOwnProperty;
1015
- var __propIsEnum$5 = Object.prototype.propertyIsEnumerable;
1016
- var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1017
- var __spreadValues$5 = (a, b) => {
1093
+ var __defProp$a = Object.defineProperty;
1094
+ var __getOwnPropSymbols$7 = Object.getOwnPropertySymbols;
1095
+ var __hasOwnProp$7 = Object.prototype.hasOwnProperty;
1096
+ var __propIsEnum$7 = Object.prototype.propertyIsEnumerable;
1097
+ var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1098
+ var __spreadValues$7 = (a, b) => {
1018
1099
  for (var prop in b || (b = {}))
1019
- if (__hasOwnProp$5.call(b, prop))
1020
- __defNormalProp$8(a, prop, b[prop]);
1021
- if (__getOwnPropSymbols$5)
1022
- for (var prop of __getOwnPropSymbols$5(b)) {
1023
- if (__propIsEnum$5.call(b, prop))
1024
- __defNormalProp$8(a, prop, b[prop]);
1100
+ if (__hasOwnProp$7.call(b, prop))
1101
+ __defNormalProp$a(a, prop, b[prop]);
1102
+ if (__getOwnPropSymbols$7)
1103
+ for (var prop of __getOwnPropSymbols$7(b)) {
1104
+ if (__propIsEnum$7.call(b, prop))
1105
+ __defNormalProp$a(a, prop, b[prop]);
1025
1106
  }
1026
1107
  return a;
1027
1108
  };
1028
- var __publicField$5 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
1029
- var __async$4 = (__this, __arguments, generator) => {
1109
+ var __objRest$2 = (source, exclude) => {
1110
+ var target = {};
1111
+ for (var prop in source)
1112
+ if (__hasOwnProp$7.call(source, prop) && exclude.indexOf(prop) < 0)
1113
+ target[prop] = source[prop];
1114
+ if (source != null && __getOwnPropSymbols$7)
1115
+ for (var prop of __getOwnPropSymbols$7(source)) {
1116
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$7.call(source, prop))
1117
+ target[prop] = source[prop];
1118
+ }
1119
+ return target;
1120
+ };
1121
+ var __async$6 = (__this, __arguments, generator) => {
1030
1122
  return new Promise((resolve, reject) => {
1031
1123
  var fulfilled = (value) => {
1032
1124
  try {
@@ -1046,288 +1138,820 @@ var Geocoder = (function (exports) {
1046
1138
  step((generator = generator.apply(__this, __arguments)).next());
1047
1139
  });
1048
1140
  };
1049
- class ResourcesControl {
1050
- constructor({
1051
- connector,
1052
- cacheId
1053
- }) {
1054
- __publicField$5(this, "cache");
1055
- __publicField$5(this, "connector");
1056
- this.connector = connector;
1057
- this.cache = new Cache({ namespace: cacheId });
1058
- }
1059
- // -------------------------------------------------------------------------
1060
- // Resource Methods
1061
- // -------------------------------------------------------------------------
1062
- /**
1063
- * Receive resource from NGW by id, keyname or search-object parameter.
1064
- * @param resource - Resource id, keyname or search-object
1065
- *
1066
- * @remarks
1067
- * Fetching resource would be cached to speed up next call
1068
- */
1069
- getOne(resource, requestOptions) {
1070
- const opt = __spreadValues$5({}, requestOptions);
1071
- if (typeof resource === "string") ; else if (typeof resource === "number") ; else if (isObject(resource)) {
1072
- if (resource.id !== void 0) {
1073
- resource.id;
1074
- } else {
1075
- if (resource.keyname) {
1076
- resource.keyname;
1077
- }
1078
- if (resource.display_name) {
1079
- resource.display_name;
1080
- }
1141
+ function lunkwillCheckResponse(lwResp) {
1142
+ const ct = lwResp.headers.get("content-type");
1143
+ return ct !== void 0 && ct !== null && ct.includes("application/vnd.lunkwill.request-summary+json");
1144
+ }
1145
+ function responseJson(response) {
1146
+ return __async$6(this, null, function* () {
1147
+ try {
1148
+ return response.json();
1149
+ } catch (e) {
1150
+ throw new Error();
1151
+ }
1152
+ });
1153
+ }
1154
+ function lunkwillResponseUrl(lwResp) {
1155
+ return __async$6(this, null, function* () {
1156
+ const lwData = yield responseJson(lwResp);
1157
+ let delay = lwData.delay_ms;
1158
+ const retry = lwData.retry_ms !== void 0 ? lwData.retry_ms : 2e3;
1159
+ const sum = `/api/lunkwill/${lwData.id}/summary`;
1160
+ const res = `/api/lunkwill/${lwData.id}/response`;
1161
+ const sleep = (msec) => new Promise((resolve) => setTimeout(resolve, msec));
1162
+ let failed = false;
1163
+ let ready = false;
1164
+ while (!ready) {
1165
+ yield sleep(failed ? retry : delay);
1166
+ failed = false;
1167
+ let lwResp2;
1168
+ let lwData2;
1169
+ try {
1170
+ lwResp2 = yield fetch(sum, { credentials: "same-origin" });
1171
+ lwData2 = yield lwResp2.json();
1172
+ } catch (e) {
1173
+ failed = true;
1174
+ continue;
1175
+ }
1176
+ switch (lwData2.status) {
1177
+ case void 0:
1178
+ throw new LunkwillError(void 0, lwData2);
1179
+ case "ready":
1180
+ ready = true;
1181
+ break;
1182
+ case "cancelled":
1183
+ throw new LunkwillRequestCancelled(lwData2);
1184
+ case "failed":
1185
+ throw new LunkwillRequestFailed(lwData2);
1186
+ case "spooled":
1187
+ case "processing":
1188
+ case "buffering":
1189
+ delay = lwData2.delay_ms;
1190
+ break;
1191
+ default:
1192
+ throw new LunkwillError(void 0, lwData2);
1081
1193
  }
1082
1194
  }
1083
- if (typeof resource === "string") {
1084
- return this._fetchResourceBy({ keyname: resource }, opt);
1085
- } else if (typeof resource === "number") {
1086
- return this._fetchResourceById(resource, opt);
1087
- } else if (isObject(resource)) {
1088
- return this._fetchResourceBy(resource, opt);
1195
+ return res;
1196
+ });
1197
+ }
1198
+ function lunkwillFetch(lwRespUrl) {
1199
+ return __async$6(this, null, function* () {
1200
+ try {
1201
+ return yield window.fetch(lwRespUrl, { credentials: "same-origin" });
1202
+ } catch (e) {
1203
+ throw new NetworksResponseError();
1089
1204
  }
1090
- return Promise.resolve(void 0);
1091
- }
1092
- getOneOrFail(resource, requestOptions) {
1093
- return this.getOne(resource, requestOptions).then((res) => {
1094
- if (res) {
1095
- return res;
1096
- }
1097
- throw new ResourceNotFoundError();
1098
- });
1099
- }
1100
- /**
1101
- * A fast way to retrieve resource ID for any resource definition.
1102
- * @param resource - Any available resource definition
1103
- *
1104
- * @remarks
1105
- * There are situations when exactly the resource id is needed
1106
- * (for example, to compose the correct request to the api)
1107
- * then this method will come in handy to facilitate the extraction of the identifier
1108
- * if the resource is specified through a keyname or other parameters.
1109
- */
1110
- getId(resource, requestOptions) {
1111
- if (typeof resource === "number") {
1112
- return Promise.resolve(resource);
1113
- } else if (typeof resource === "string" || isObject(resource)) {
1114
- return this.getOne(resource, requestOptions).then((res) => {
1115
- if (res) {
1116
- return res.resource.id;
1205
+ });
1206
+ }
1207
+ const mediaContentTypes = [
1208
+ "application/pdf",
1209
+ "image/png",
1210
+ "image/jpeg",
1211
+ "image/tiff",
1212
+ "text/csv"
1213
+ ];
1214
+ const mediaContentTypesRegex = new RegExp(mediaContentTypes.join("|"));
1215
+ function isMediaContentType(contentType) {
1216
+ return mediaContentTypesRegex.test(contentType);
1217
+ }
1218
+ function encodeQueryParams(value) {
1219
+ const result = [];
1220
+ for (const [k, v] of Object.entries(value)) {
1221
+ if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
1222
+ result.push(`${k}=${encodeURIComponent(v)}`);
1223
+ } else if (Array.isArray(v)) {
1224
+ result.push(`${k}=${v.map(encodeURIComponent).join(",")}`);
1225
+ } else {
1226
+ for (const [sk, sv] of Object.entries(v)) {
1227
+ const ske = `${k}[${encodeURIComponent(sk)}]`;
1228
+ if (typeof sv === "string" || typeof sv === "number" || typeof sv === "boolean") {
1229
+ result.push(`${ske}=${encodeURIComponent(sv)}`);
1230
+ } else if (Array.isArray(sv)) {
1231
+ const sve = sv.map(encodeURIComponent);
1232
+ result.push(`${ske}=${sve.join(",")}`);
1117
1233
  }
1118
- });
1234
+ }
1119
1235
  }
1120
- return Promise.resolve(void 0);
1121
1236
  }
1122
- /**
1123
- * A fast way to retrieve resource ID for any resource definition.
1124
- * @param resource - Any available resource definition
1125
- *
1126
- * @remarks
1127
- * Similar with {@link NgwConnector.getResourceId | getResourceId} but rise error if resource is not exist.
1128
- * To not make one more checks if the resource is definitely exists
1129
- */
1130
- getIdOrFail(resource, requestOptions) {
1131
- return this.getId(resource, requestOptions).then((resp) => {
1132
- if (resp === void 0) {
1133
- throw new Error();
1134
- }
1135
- return resp;
1136
- });
1237
+ return result.join("&");
1238
+ }
1239
+ function generateUrl(path, query) {
1240
+ let urlParams = "";
1241
+ if (query !== void 0) {
1242
+ urlParams = "?" + encodeQueryParams(query);
1137
1243
  }
1138
- getMany(resource, requestOptions) {
1139
- return this._resourceCacheFilter(resource).then((items) => {
1140
- if (!items.length) {
1141
- const query = {};
1142
- if (resource.keyname) {
1143
- query.keyname = resource.keyname;
1244
+ return path + urlParams;
1245
+ }
1246
+ function request(path, options, cacheEngine) {
1247
+ return __async$6(this, null, function* () {
1248
+ var _b;
1249
+ const defaults = {
1250
+ method: "GET",
1251
+ credentials: "same-origin",
1252
+ headers: {}
1253
+ };
1254
+ const _a = __spreadValues$7(__spreadValues$7({}, defaults), options), {
1255
+ withCredentials,
1256
+ responseType,
1257
+ cacheProps,
1258
+ cacheName,
1259
+ lunkwill,
1260
+ cache,
1261
+ query,
1262
+ json
1263
+ } = _a, opt = __objRest$2(_a, [
1264
+ "withCredentials",
1265
+ "responseType",
1266
+ "cacheProps",
1267
+ "cacheName",
1268
+ "lunkwill",
1269
+ "cache",
1270
+ "query",
1271
+ "json"
1272
+ ]);
1273
+ if (withCredentials) {
1274
+ opt.credentials = "include";
1275
+ }
1276
+ let useLunkwill = false;
1277
+ if (lunkwill !== void 0) {
1278
+ lunkwill.toHeaders(opt.headers || {});
1279
+ useLunkwill = true;
1280
+ }
1281
+ const lunkwillReturnUrl = !!opt.lunkwillReturnUrl;
1282
+ delete opt.lunkwillReturnUrl;
1283
+ if (json !== void 0) {
1284
+ opt.body = JSON.stringify(json);
1285
+ const headers = opt.headers || {};
1286
+ headers["Content-Type"] = "application/json";
1287
+ opt.headers = headers;
1288
+ }
1289
+ const url = generateUrl(path, query);
1290
+ const makeRequest = () => __async$6(this, null, function* () {
1291
+ let response;
1292
+ try {
1293
+ response = yield fetch(url, opt);
1294
+ } catch (e) {
1295
+ if (e.name === "AbortError") {
1296
+ throw e;
1297
+ }
1298
+ throw new NetworksResponseError();
1299
+ }
1300
+ if (useLunkwill && lunkwillCheckResponse(response)) {
1301
+ const lwRespUrl = yield lunkwillResponseUrl(response);
1302
+ if (lunkwillReturnUrl) {
1303
+ return lwRespUrl;
1304
+ }
1305
+ response = yield lunkwillFetch(lwRespUrl);
1306
+ }
1307
+ const respCType = response.headers.get("content-type");
1308
+ const respJSON = respCType && (respCType.includes("application/json") || respCType.includes("application/vnd.lunkwill.request-summary+json"));
1309
+ let body;
1310
+ try {
1311
+ const respMedia = respCType && isMediaContentType(respCType);
1312
+ if (responseType === "blob" || respMedia) {
1313
+ body = yield response.blob();
1314
+ } else if (respJSON) {
1315
+ body = yield response.json();
1144
1316
  } else {
1145
- Object.assign(query, resourceToQuery(resource));
1317
+ throw new InvalidResponseError();
1146
1318
  }
1147
- return this.connector.get("resource.search", requestOptions, __spreadValues$5({
1148
- serialization: "full"
1149
- }, query)).then((resources) => {
1150
- if ((requestOptions == null ? void 0 : requestOptions.cache) && resources) {
1151
- for (const x of resources) {
1152
- this.cache.add("resource.item", Promise.resolve(x), {
1153
- id: x.resource.id
1154
- });
1155
- }
1156
- }
1157
- return resources;
1158
- });
1319
+ } catch (e) {
1320
+ if (e.name === "AbortError" || e instanceof InvalidResponseError) {
1321
+ throw e;
1322
+ }
1323
+ throw new InvalidResponseError();
1159
1324
  }
1160
- return items;
1325
+ if (400 <= response.status && response.status <= 599) {
1326
+ throw new ServerResponseError(body);
1327
+ }
1328
+ return body;
1161
1329
  });
1162
- }
1163
- getParent(resource, requestOptions) {
1164
- return this.getOne(resource, requestOptions).then((child) => {
1165
- if (child) {
1166
- return this.getOne(child.resource.parent.id, requestOptions);
1330
+ if (cacheEngine && cache && ((_b = opt.method) == null ? void 0 : _b.toUpperCase()) === "GET") {
1331
+ const cacheOptions = cacheProps ? cacheProps : __spreadValues$7({}, objectRemoveEmpty({
1332
+ withCredentials,
1333
+ responseType
1334
+ }));
1335
+ return cacheEngine.add(cacheName || url, makeRequest, cacheOptions, false);
1336
+ }
1337
+ return makeRequest();
1338
+ });
1339
+ }
1340
+
1341
+ var __defProp$9 = Object.defineProperty;
1342
+ var __defProps$3 = Object.defineProperties;
1343
+ var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
1344
+ var __getOwnPropSymbols$6 = Object.getOwnPropertySymbols;
1345
+ var __hasOwnProp$6 = Object.prototype.hasOwnProperty;
1346
+ var __propIsEnum$6 = Object.prototype.propertyIsEnumerable;
1347
+ var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1348
+ var __spreadValues$6 = (a, b) => {
1349
+ for (var prop in b || (b = {}))
1350
+ if (__hasOwnProp$6.call(b, prop))
1351
+ __defNormalProp$9(a, prop, b[prop]);
1352
+ if (__getOwnPropSymbols$6)
1353
+ for (var prop of __getOwnPropSymbols$6(b)) {
1354
+ if (__propIsEnum$6.call(b, prop))
1355
+ __defNormalProp$9(a, prop, b[prop]);
1356
+ }
1357
+ return a;
1358
+ };
1359
+ var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
1360
+ var __objRest$1 = (source, exclude) => {
1361
+ var target = {};
1362
+ for (var prop in source)
1363
+ if (__hasOwnProp$6.call(source, prop) && exclude.indexOf(prop) < 0)
1364
+ target[prop] = source[prop];
1365
+ if (source != null && __getOwnPropSymbols$6)
1366
+ for (var prop of __getOwnPropSymbols$6(source)) {
1367
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$6.call(source, prop))
1368
+ target[prop] = source[prop];
1369
+ }
1370
+ return target;
1371
+ };
1372
+ var __async$5 = (__this, __arguments, generator) => {
1373
+ return new Promise((resolve, reject) => {
1374
+ var fulfilled = (value) => {
1375
+ try {
1376
+ step(generator.next(value));
1377
+ } catch (e) {
1378
+ reject(e);
1379
+ }
1380
+ };
1381
+ var rejected = (value) => {
1382
+ try {
1383
+ step(generator.throw(value));
1384
+ } catch (e) {
1385
+ reject(e);
1386
+ }
1387
+ };
1388
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
1389
+ step((generator = generator.apply(__this, __arguments)).next());
1390
+ });
1391
+ };
1392
+ function routeURL(name, baseUrl, routeData, ...rest) {
1393
+ const [template, ...params] = routeData[name];
1394
+ const first = rest[0];
1395
+ let sub;
1396
+ if (first === void 0) {
1397
+ sub = [];
1398
+ } else if (typeof first === "object" && first !== null) {
1399
+ if (rest.length > 1) {
1400
+ throw new Error("Too many arguments for route(name, object)!");
1401
+ }
1402
+ sub = [];
1403
+ for (const [p, v] of Object.entries(first)) {
1404
+ sub[params.indexOf(p)] = String(v);
1405
+ }
1406
+ } else {
1407
+ sub = rest.map((v) => String(v));
1408
+ }
1409
+ return fixUrlStr(
1410
+ baseUrl + template.replace(/\{(\w+)\}/g, function(m, a) {
1411
+ const idx = parseInt(a);
1412
+ const value = sub[idx];
1413
+ if (value === void 0) {
1414
+ const msg = `Undefined parameter ${idx} in "${template}".`;
1415
+ throw new Error(msg);
1416
+ }
1417
+ return String(value);
1418
+ })
1419
+ );
1420
+ }
1421
+ function route(name, connector, ...rest) {
1422
+ const result = {
1423
+ url: (opt) => __async$5(this, null, function* () {
1424
+ var _a;
1425
+ const routeData = yield connector.connect();
1426
+ const template = routeURL(
1427
+ name,
1428
+ (_a = connector.options.baseUrl) != null ? _a : "",
1429
+ routeData,
1430
+ ...rest
1431
+ );
1432
+ return generateUrl(template, opt == null ? void 0 : opt.query);
1433
+ })
1434
+ };
1435
+ const methods = ["get", "post", "put", "delete", "patch"];
1436
+ for (const method of methods) {
1437
+ const methodResp = (requestOptions) => __async$5(this, null, function* () {
1438
+ var _b;
1439
+ const _a = requestOptions || {}, { headers: optHeaders } = _a, restOpt = __objRest$1(_a, ["headers"]);
1440
+ const routeData = yield connector.connect();
1441
+ const template = routeURL(
1442
+ name,
1443
+ (_b = connector.options.baseUrl) != null ? _b : "",
1444
+ routeData,
1445
+ ...rest
1446
+ );
1447
+ const headers = objectRemoveEmpty(__spreadValues$6(__spreadValues$6({}, connector.getAuthorizationHeaders()), optHeaders != null ? optHeaders : {}));
1448
+ return request(
1449
+ template,
1450
+ __spreadProps$3(__spreadValues$6({
1451
+ headers
1452
+ }, restOpt), {
1453
+ method
1454
+ }),
1455
+ connector.cache
1456
+ );
1457
+ });
1458
+ result[method] = methodResp;
1459
+ }
1460
+ return result;
1461
+ }
1462
+
1463
+ var __defProp$8 = Object.defineProperty;
1464
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1465
+ var __publicField$5 = (obj, key, value) => __defNormalProp$8(obj, key + "" , value);
1466
+ class NetworkError extends Error {
1467
+ constructor(url) {
1468
+ super();
1469
+ __publicField$5(this, "name", "NetworkError");
1470
+ Object.setPrototypeOf(this, NetworkError.prototype);
1471
+ this.message = `Unable to request ${url}.
1472
+ Possibly invalid NGW URL entered or CORS not configured to get request from ${location.origin}`;
1473
+ }
1474
+ }
1475
+
1476
+ function isObject(val) {
1477
+ return Object.prototype.toString.call(val) === "[object Object]";
1478
+ }
1479
+
1480
+ let loadData;
1481
+ {
1482
+ loadData = (url, callback, options = {}, error, onCancel) => {
1483
+ options.method = options.method || "GET";
1484
+ const xhr = new XMLHttpRequest();
1485
+ xhr.open(options.method || "GET", url, true);
1486
+ if (options.responseType === "blob") {
1487
+ xhr.responseType = options.responseType;
1488
+ }
1489
+ const getResponseText = () => {
1490
+ try {
1491
+ return JSON.parse(xhr.responseText);
1492
+ } catch (er) {
1493
+ return xhr.responseText;
1494
+ }
1495
+ };
1496
+ const processingResponse = (forError = false) => {
1497
+ const cb = forError ? error : callback;
1498
+ if (options.responseType === "blob") {
1499
+ cb(xhr.response);
1500
+ } else {
1501
+ if (xhr.responseText) {
1502
+ cb(getResponseText());
1503
+ } else {
1504
+ error({ message: "" });
1505
+ }
1506
+ }
1507
+ };
1508
+ xhr.onload = () => {
1509
+ if ([401, 403, 404, 422, 500].indexOf(xhr.status) !== -1) {
1510
+ error(new NgwError(getResponseText()));
1511
+ }
1512
+ processingResponse();
1513
+ };
1514
+ xhr.onerror = (er) => {
1515
+ if (xhr.status === 0) {
1516
+ error(new NetworkError(url));
1517
+ } else {
1518
+ error(er);
1519
+ }
1520
+ };
1521
+ xhr.upload.onprogress = function(e) {
1522
+ if (e.lengthComputable) {
1523
+ const percentComplete = e.loaded / e.total * 100;
1524
+ if (options.onProgress) {
1525
+ options.onProgress(percentComplete, e);
1526
+ }
1527
+ }
1528
+ };
1529
+ const headers = options.headers;
1530
+ if (headers) {
1531
+ for (const h in headers) {
1532
+ const header = headers[h];
1533
+ if (typeof header === "string") {
1534
+ xhr.setRequestHeader(h, header);
1535
+ }
1536
+ }
1537
+ }
1538
+ if (options.withCredentials !== void 0) {
1539
+ xhr.withCredentials = options.withCredentials;
1540
+ }
1541
+ let data;
1542
+ if (options.file) {
1543
+ data = new FormData();
1544
+ data.append("file", options.file);
1545
+ if (options.data) {
1546
+ for (const d in options.data) {
1547
+ data.append(d, data[d]);
1548
+ }
1549
+ }
1550
+ } else {
1551
+ data = options.data ? typeof options.data === "string" ? options.data : JSON.stringify(options.data) : null;
1552
+ }
1553
+ if (onCancel) {
1554
+ onCancel(() => {
1555
+ xhr.abort();
1556
+ });
1557
+ }
1558
+ xhr.send(data);
1559
+ };
1560
+ }
1561
+
1562
+ const templateRe = /\{ *([\w_-]+) *\}/g;
1563
+ function template(str, data) {
1564
+ return str.replace(templateRe, (s, key) => {
1565
+ let value = data[key];
1566
+ if (value === void 0) {
1567
+ throw new Error("No value provided for letiable " + s);
1568
+ } else if (typeof value === "function") {
1569
+ value = value(data);
1570
+ }
1571
+ return value;
1572
+ });
1573
+ }
1574
+
1575
+ var __defProp$7 = Object.defineProperty;
1576
+ var __defProps$2 = Object.defineProperties;
1577
+ var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
1578
+ var __getOwnPropSymbols$5 = Object.getOwnPropertySymbols;
1579
+ var __hasOwnProp$5 = Object.prototype.hasOwnProperty;
1580
+ var __propIsEnum$5 = Object.prototype.propertyIsEnumerable;
1581
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1582
+ var __spreadValues$5 = (a, b) => {
1583
+ for (var prop in b || (b = {}))
1584
+ if (__hasOwnProp$5.call(b, prop))
1585
+ __defNormalProp$7(a, prop, b[prop]);
1586
+ if (__getOwnPropSymbols$5)
1587
+ for (var prop of __getOwnPropSymbols$5(b)) {
1588
+ if (__propIsEnum$5.call(b, prop))
1589
+ __defNormalProp$7(a, prop, b[prop]);
1590
+ }
1591
+ return a;
1592
+ };
1593
+ var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
1594
+ var __objRest = (source, exclude) => {
1595
+ var target = {};
1596
+ for (var prop in source)
1597
+ if (__hasOwnProp$5.call(source, prop) && exclude.indexOf(prop) < 0)
1598
+ target[prop] = source[prop];
1599
+ if (source != null && __getOwnPropSymbols$5)
1600
+ for (var prop of __getOwnPropSymbols$5(source)) {
1601
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$5.call(source, prop))
1602
+ target[prop] = source[prop];
1603
+ }
1604
+ return target;
1605
+ };
1606
+ var __publicField$4 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
1607
+ var __async$4 = (__this, __arguments, generator) => {
1608
+ return new Promise((resolve, reject) => {
1609
+ var fulfilled = (value) => {
1610
+ try {
1611
+ step(generator.next(value));
1612
+ } catch (e) {
1613
+ reject(e);
1614
+ }
1615
+ };
1616
+ var rejected = (value) => {
1617
+ try {
1618
+ step(generator.throw(value));
1619
+ } catch (e) {
1620
+ reject(e);
1621
+ }
1622
+ };
1623
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
1624
+ step((generator = generator.apply(__this, __arguments)).next());
1625
+ });
1626
+ };
1627
+ let ID = 0;
1628
+ let REQUEST_ID = 0;
1629
+ class NgwConnector {
1630
+ constructor(options) {
1631
+ this.options = options;
1632
+ __publicField$4(this, "id", ID++);
1633
+ __publicField$4(this, "emitter", new EventEmitter());
1634
+ __publicField$4(this, "user");
1635
+ __publicField$4(this, "cache");
1636
+ __publicField$4(this, "withCredentials");
1637
+ __publicField$4(this, "client", `NextGIS-NGW-Connector/${pkg.version}`);
1638
+ __publicField$4(this, "routeStr", "/api/component/pyramid/route");
1639
+ __publicField$4(this, "activeRequests", {});
1640
+ __publicField$4(this, "requestTransform");
1641
+ const exist = findConnector(options);
1642
+ this.cache = new Cache({ namespace: options.cacheId });
1643
+ if (exist) {
1644
+ return exist;
1645
+ } else {
1646
+ const { route: route2, requestTransform, withCredentials } = this.options;
1647
+ if (route2) {
1648
+ this.routeStr = route2;
1649
+ }
1650
+ if (requestTransform) {
1651
+ this.requestTransform = requestTransform;
1652
+ }
1653
+ if (withCredentials !== void 0) {
1654
+ this.withCredentials = withCredentials;
1655
+ }
1656
+ addConnector(this);
1657
+ }
1658
+ }
1659
+ static create(options) {
1660
+ return new this(options);
1661
+ }
1662
+ /**
1663
+ * Clear the cache.
1664
+ */
1665
+ clearCache() {
1666
+ this.cache.clean();
1667
+ }
1668
+ setRequestTransform(requestTransform) {
1669
+ this.requestTransform = requestTransform;
1670
+ }
1671
+ /**
1672
+ * Fast way to specify the connection address to NextGIS Web.
1673
+ * The current connection will be severed.
1674
+ * @param baseUrl - NGW url
1675
+ */
1676
+ setNgw(baseUrl) {
1677
+ this.logout();
1678
+ this.options.baseUrl = baseUrl;
1679
+ addConnector(this);
1680
+ }
1681
+ /**
1682
+ * Establishing a connection with NextGIS Web to fulfill all other requests.
1683
+ * @remarks
1684
+ * This method need not be called manually as it is used when forming a request in {@link apiRequest | apiRequest}.
1685
+ * Can be used to check connection.
1686
+ * @example
1687
+ * ```javascript
1688
+ * const connector = new NgwConnector({ baseUrl: 'https://demo.nextgis.com' });
1689
+ * connector.connect()
1690
+ * .then(() => console.log('Ok'))
1691
+ * .catch((er) => console.log('Connection problem', er));
1692
+ * ```
1693
+ */
1694
+ connect() {
1695
+ return __async$4(this, null, function* () {
1696
+ const auth = this.options.auth;
1697
+ if (auth) {
1698
+ const { login, password } = auth;
1699
+ if (login && password) {
1700
+ yield this._login({ login, password });
1701
+ }
1167
1702
  }
1168
- return Promise.resolve(void 0);
1703
+ const routeUrl = `${this.routeStr}?client=${this.client}`;
1704
+ return yield this.makeQuery(
1705
+ routeUrl,
1706
+ {},
1707
+ {
1708
+ cacheName: "route",
1709
+ cache: true,
1710
+ cacheProps: {
1711
+ id: this.id,
1712
+ auth,
1713
+ baseUrl: this.options.baseUrl
1714
+ }
1715
+ }
1716
+ );
1169
1717
  });
1170
1718
  }
1171
- getChildrenOf(resource, requestOptions) {
1172
- return this.getIdOrFail(resource).then(
1173
- (parent) => this._getChildrenOf(parent, requestOptions)
1174
- );
1719
+ /**
1720
+ * Quick way to change NextGIS Web user.
1721
+ * @param credentials - New user credentials
1722
+ */
1723
+ login(credentials, options) {
1724
+ this.logout();
1725
+ addConnector(this);
1726
+ return this._login(credentials, options);
1175
1727
  }
1176
- update(resource, data) {
1177
- return this.getId(resource).then((id) => {
1178
- if (id !== void 0) {
1179
- return this.connector.put("resource.item", { data }, { id });
1728
+ /**
1729
+ * Disconnecting a user. Aborting all current requests
1730
+ */
1731
+ logout() {
1732
+ this.abort();
1733
+ removeConnector(this);
1734
+ this.options.auth = void 0;
1735
+ this.user = void 0;
1736
+ this.clearCache();
1737
+ this.emitter.emit("logout");
1738
+ }
1739
+ getUserInfo(credentials, options) {
1740
+ return __async$4(this, null, function* () {
1741
+ if (this.user && this.user.id) {
1742
+ return this.user;
1743
+ }
1744
+ if (credentials) {
1745
+ this.options.auth = credentials;
1180
1746
  }
1747
+ const options_ = __spreadValues$5({
1748
+ headers: this.getAuthorizationHeaders(credentials),
1749
+ cache: true
1750
+ }, options);
1751
+ return this.makeQuery(
1752
+ "/api/component/auth/current_user",
1753
+ {},
1754
+ options_
1755
+ );
1181
1756
  });
1182
1757
  }
1183
1758
  /**
1184
- * Fast way to delete resource from NGW and clean cache.
1185
- * @param resource - Resource definition
1759
+ * Obtaining the required Headers for authentication of requests in the NGW.
1186
1760
  */
1187
- delete(resource) {
1188
- return this.getId(resource).then((id) => {
1189
- if (id !== void 0) {
1190
- return this.connector.delete("resource.item", null, { id }).then(() => {
1191
- this._cleanResourceItemCache(id);
1192
- return void 0;
1193
- });
1761
+ getAuthorizationHeaders(credentials) {
1762
+ const client = this.makeClientId(credentials);
1763
+ if (client) {
1764
+ return {
1765
+ Authorization: `Basic ${client}`
1766
+ };
1767
+ }
1768
+ return {};
1769
+ }
1770
+ makeClientId(credentials) {
1771
+ credentials = credentials || this.options.auth;
1772
+ if (credentials) {
1773
+ const { login, password } = credentials;
1774
+ const encodedStr = [login, password].map(encodeURIComponent).join(":");
1775
+ {
1776
+ return window.btoa(encodedStr);
1194
1777
  }
1195
- });
1778
+ }
1196
1779
  }
1197
- _getChildrenOf(parent, requestOptions, _items = []) {
1198
- return this.connector.get("resource.collection", requestOptions, {
1199
- parent
1200
- }).then((items) => {
1201
- const recursivePromises = [];
1202
- for (const item of items) {
1203
- if (requestOptions == null ? void 0 : requestOptions.cache) {
1204
- this.cache.add("resource.item", Promise.resolve(item), {
1205
- id: item.resource.id
1206
- });
1207
- }
1208
- _items.push(item);
1209
- if ((requestOptions == null ? void 0 : requestOptions.recursive) && item.resource.children) {
1210
- recursivePromises.push(
1211
- this._getChildrenOf(item.resource.id, requestOptions, _items)
1212
- );
1780
+ /** Stop all api requests */
1781
+ abort() {
1782
+ for (const abortController of Object.values(this.activeRequests)) {
1783
+ abortController.abort();
1784
+ }
1785
+ this.activeRequests = {};
1786
+ }
1787
+ getActiveApiRequests() {
1788
+ return __spreadValues$5({}, this.activeRequests);
1789
+ }
1790
+ route(name, ...rest) {
1791
+ return route(name, this, ...rest);
1792
+ }
1793
+ /**
1794
+ * Send request to NGW.
1795
+ * @param url - URL address to NGW
1796
+ * @param params - Query params
1797
+ * @param options - Request options
1798
+ */
1799
+ makeQuery(_0, _1) {
1800
+ return __async$4(this, arguments, function* (url, params, options = {}) {
1801
+ var _b;
1802
+ url = (this.options.baseUrl ? this.options.baseUrl : "") + url;
1803
+ if (!url) {
1804
+ throw new Error("Empty `url` not allowed");
1805
+ }
1806
+ if (params) {
1807
+ const _a = params, restParams = __objRest(_a, ["paramList"]);
1808
+ url = template(url, restParams);
1809
+ }
1810
+ url = encodeURI(fixUrlStr(url));
1811
+ options = __spreadValues$5({ withCredentials: this.withCredentials }, options);
1812
+ const {
1813
+ cache,
1814
+ signal: externalSignal,
1815
+ method = "GET",
1816
+ headers,
1817
+ cacheName,
1818
+ cacheProps,
1819
+ responseType,
1820
+ withCredentials
1821
+ } = options;
1822
+ const internalAbortController = new AbortController();
1823
+ const internalSignal = internalAbortController.signal;
1824
+ if (externalSignal) {
1825
+ if (externalSignal.aborted) {
1826
+ throw new AbortError();
1213
1827
  }
1828
+ externalSignal.addEventListener("abort", () => {
1829
+ internalAbortController.abort();
1830
+ });
1214
1831
  }
1215
- if (recursivePromises.length) {
1216
- return Promise.all(recursivePromises).then(() => {
1217
- return _items;
1832
+ options.signal = internalSignal;
1833
+ const createPromise = () => __async$4(this, null, function* () {
1834
+ const id = REQUEST_ID++;
1835
+ this.activeRequests[id] = internalAbortController;
1836
+ try {
1837
+ return this._loadData(url, options);
1838
+ } finally {
1839
+ this._cleanActiveRequest(id);
1840
+ }
1841
+ });
1842
+ if (cache && method === "GET") {
1843
+ const cacheOptions = cacheProps ? cacheProps : __spreadProps$2(__spreadValues$5({}, objectRemoveEmpty({
1844
+ headers,
1845
+ withCredentials,
1846
+ responseType,
1847
+ baseUrl: this.options.baseUrl,
1848
+ userId: (_b = this.user) == null ? void 0 : _b.id
1849
+ })), {
1850
+ params
1218
1851
  });
1852
+ return this.cache.add(
1853
+ cacheName || url,
1854
+ createPromise,
1855
+ cacheOptions,
1856
+ false
1857
+ );
1219
1858
  }
1220
- return _items;
1859
+ return createPromise();
1221
1860
  });
1222
1861
  }
1223
- _cleanResourceItemCache(id) {
1224
- return __async$4(this, null, function* () {
1862
+ _loadData(url, options) {
1863
+ options.responseType = options.responseType || "json";
1864
+ return new Promise((resolve, reject) => {
1225
1865
  var _a;
1226
- const all = this.cache.all();
1227
- const toDelete = [];
1228
- for (const c of all) {
1229
- const cid = (_a = c.props) == null ? void 0 : _a.id;
1230
- if (["resource.item", "resource"].includes(c.key) && cid !== void 0) {
1231
- if (typeof cid === "number") {
1232
- if (cid === id) {
1233
- toDelete.push(c);
1234
- }
1235
- } else {
1236
- const rid = yield this.getId(cid);
1237
- if (rid === id) {
1238
- toDelete.push(c);
1239
- }
1240
- }
1866
+ if (this.user) {
1867
+ options = options || {};
1868
+ options.headers = __spreadValues$5(__spreadValues$5({}, this.getAuthorizationHeaders()), options.headers);
1869
+ }
1870
+ if (this.requestTransform) {
1871
+ const [transUrl, transOptions] = this.requestTransform(url, options);
1872
+ url = transUrl;
1873
+ options = transOptions;
1874
+ }
1875
+ let runOnAbort = void 0;
1876
+ loadData(url, resolve, options, reject, (handler) => {
1877
+ runOnAbort = handler;
1878
+ });
1879
+ (_a = options.signal) == null ? void 0 : _a.addEventListener("abort", () => {
1880
+ if (runOnAbort !== void 0) {
1881
+ runOnAbort();
1882
+ }
1883
+ reject(new AbortError());
1884
+ });
1885
+ }).catch((httpError) => {
1886
+ if (httpError.name !== "AbortError") {
1887
+ {
1888
+ console.warn("DEV WARN", httpError);
1889
+ }
1890
+ const er = this._handleHttpError(httpError);
1891
+ if (er) {
1892
+ throw er;
1241
1893
  }
1242
1894
  }
1243
- for (const d of toDelete) {
1244
- this.cache.delete(d);
1895
+ throw httpError;
1896
+ });
1897
+ }
1898
+ _login(credentials, options) {
1899
+ return __async$4(this, null, function* () {
1900
+ try {
1901
+ const data = yield this.getUserInfo(credentials, options);
1902
+ this.user = data;
1903
+ this.emitter.emit("login", data);
1904
+ return data;
1905
+ } catch (er) {
1906
+ this.emitter.emit("login:error", er);
1907
+ throw er;
1245
1908
  }
1246
1909
  });
1247
1910
  }
1248
- _fetchResourceById(id, requestOptions) {
1249
- return this.connector.get("resource.item", requestOptions, { id });
1250
- }
1251
- _fetchResourceBy(resource, requestOptions) {
1252
- return this.getMany(resource, requestOptions).then((resources) => {
1253
- return resources[0];
1254
- });
1255
- }
1256
- _resourceCacheFilter(resource) {
1257
- return Promise.all(this.cache.matchAll("resource.item")).then(
1258
- (resources) => {
1259
- const items = [];
1260
- resources.filter((x) => {
1261
- if (x) {
1262
- if (resource.keyname && x.resource.keyname) {
1263
- return resource.keyname === x.resource.keyname;
1264
- }
1265
- if (defined(resource.id) && defined(x.resource.id)) {
1266
- return resource.id === x.resource.id;
1267
- }
1268
- return resourceCompare(resource, x.resource);
1269
- }
1270
- });
1271
- return items;
1272
- }
1273
- );
1911
+ _cleanActiveRequest(requestId) {
1912
+ delete this.activeRequests[requestId];
1274
1913
  }
1275
- }
1276
-
1277
- const CONNECTORS = [];
1278
- function addConnector(connector) {
1279
- CONNECTORS.push(connector);
1280
- }
1281
- function findConnector(options) {
1282
- return CONNECTORS.find((x) => {
1283
- if (x.options.baseUrl === options.baseUrl) {
1284
- if (options.auth) {
1285
- if (x.options.auth) {
1286
- return objectDeepEqual(x.options.auth, options.auth);
1914
+ _handleHttpError(er) {
1915
+ if (er) {
1916
+ if (er instanceof NgwError) {
1917
+ if (er.exception === "nextgisweb.resource.exception.ResourceNotFound") {
1918
+ throw new ResourceNotFoundError(er);
1919
+ } else if (er.exception === "nextgisweb.core.exception.InsufficientPermissions") {
1920
+ throw new InsufficientPermissionsError(er);
1287
1921
  }
1288
- } else {
1289
- return true;
1290
1922
  }
1291
1923
  }
1292
- });
1293
- }
1294
- function removeConnector(connector) {
1295
- const index = CONNECTORS.indexOf(connector);
1296
- if (index !== -1) {
1297
- CONNECTORS.splice(index, 1);
1298
- }
1299
- }
1300
-
1301
- class AbortError extends Error {
1302
- constructor(message = "AbortError") {
1303
- super(message);
1304
- this.name = "AbortError";
1924
+ return er;
1305
1925
  }
1306
1926
  }
1927
+ __publicField$4(NgwConnector, "errors", {
1928
+ NgwError,
1929
+ ResourceNotFoundError
1930
+ });
1307
1931
 
1308
- var __defProp$7 = Object.defineProperty;
1309
- var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1310
- var __publicField$4 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
1311
- class InsufficientPermissionsError extends NgwError {
1312
- constructor(obj) {
1313
- super(obj);
1314
- __publicField$4(this, "name", "InsufficientPermissionsError");
1315
- __publicField$4(this, "exception", "nextgisweb.core.exception.InsufficientPermissions");
1316
- Object.setPrototypeOf(this, InsufficientPermissionsError.prototype);
1317
- }
1932
+ function resourceCompare(res1, res2) {
1933
+ return objectDeepEqual(res1, res2);
1318
1934
  }
1319
1935
 
1320
- const templateRe = /\{ *([\w_-]+) *\}/g;
1321
- function template(str, data) {
1322
- return str.replace(templateRe, (s, key) => {
1323
- let value = data[key];
1324
- if (value === void 0) {
1325
- throw new Error("No value provided for letiable " + s);
1326
- } else if (typeof value === "function") {
1327
- value = value(data);
1936
+ const exclude = ["description"];
1937
+ function resourceToQuery(resource, prefix = "") {
1938
+ prefix = prefix ? prefix + "__" : "";
1939
+ const query = {};
1940
+ for (const [key, value] of Object.entries(resource)) {
1941
+ if (exclude.indexOf(key) === -1) {
1942
+ if (isObject(value)) {
1943
+ if (key === "owner_user") {
1944
+ const children = resourceToQuery(value, key);
1945
+ Object.assign(query, children);
1946
+ } else if (key === "parent" && "id" in value) {
1947
+ query.parent_id = value.id;
1948
+ }
1949
+ } else if (defined(value)) {
1950
+ query[prefix + key] = value;
1951
+ }
1328
1952
  }
1329
- return value;
1330
- });
1953
+ }
1954
+ return query;
1331
1955
  }
1332
1956
 
1333
1957
  var __defProp$6 = Object.defineProperty;
@@ -1346,6 +1970,7 @@ var Geocoder = (function (exports) {
1346
1970
  }
1347
1971
  return a;
1348
1972
  };
1973
+ var __publicField$3 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
1349
1974
  var __async$3 = (__this, __arguments, generator) => {
1350
1975
  return new Promise((resolve, reject) => {
1351
1976
  var fulfilled = (value) => {
@@ -1366,184 +1991,250 @@ var Geocoder = (function (exports) {
1366
1991
  step((generator = generator.apply(__this, __arguments)).next());
1367
1992
  });
1368
1993
  };
1369
- function apiRequest(opt) {
1370
- return __async$3(this, null, function* () {
1371
- const { params, name, connector, requestOptions } = opt;
1372
- const apiItems = yield connector.connect();
1373
- let apiItem = apiItems && apiItems[name];
1374
- if (apiItem) {
1375
- apiItem = [...apiItem];
1376
- let url = apiItem.shift();
1377
- if (apiItem.length) {
1378
- const replaceParams = {};
1379
- for (let fry = 0; fry < apiItem.length; fry++) {
1380
- const arg = apiItem[fry];
1381
- replaceParams[fry] = `{${arg}}`;
1382
- if (params[arg] === void 0) {
1383
- throw new Error(`\`${arg}\` URL API argument is not specified`);
1384
- }
1385
- }
1386
- if (url) {
1387
- url = template(url, replaceParams);
1388
- }
1389
- }
1390
- if (params) {
1391
- const paramArray = [];
1392
- const paramList = params.paramList;
1393
- if (Array.isArray(paramList)) {
1394
- paramList.forEach(([key, value]) => {
1395
- paramArray.push(`${key}=${value}`);
1396
- });
1397
- }
1398
- for (const p in params) {
1399
- if (apiItem.indexOf(p) === -1) {
1400
- paramArray.push(`${p}=${params[p]}`);
1401
- }
1994
+ class ResourcesControl {
1995
+ constructor({
1996
+ connector,
1997
+ cacheId
1998
+ }) {
1999
+ __publicField$3(this, "cache");
2000
+ __publicField$3(this, "connector");
2001
+ this.connector = connector;
2002
+ this.cache = new Cache({ namespace: cacheId });
2003
+ }
2004
+ // -------------------------------------------------------------------------
2005
+ // Resource Methods
2006
+ // -------------------------------------------------------------------------
2007
+ /**
2008
+ * Receive resource from NGW by id, keyname or search-object parameter.
2009
+ * @param resource - Resource id, keyname or search-object
2010
+ *
2011
+ * @remarks
2012
+ * Fetching resource would be cached to speed up next call
2013
+ */
2014
+ getOne(resource, requestOptions) {
2015
+ const opt = __spreadValues$4({}, requestOptions);
2016
+ if (typeof resource === "string") ; else if (typeof resource === "number") ; else if (isObject(resource)) {
2017
+ if (resource.id !== void 0) {
2018
+ resource.id;
2019
+ } else {
2020
+ if (resource.keyname) {
2021
+ resource.keyname;
1402
2022
  }
1403
- if (paramArray.length) {
1404
- url = `${url}?${paramArray.join("&")}`;
2023
+ if (resource.display_name) {
2024
+ resource.display_name;
1405
2025
  }
1406
2026
  }
1407
- if (url) {
1408
- return connector.makeQuery(url, params, __spreadValues$4({
1409
- cacheName: name
1410
- }, requestOptions));
1411
- } else {
1412
- throw new Error("Request URL is not set");
1413
- }
1414
- } else {
1415
- return void 0;
1416
2027
  }
1417
- });
1418
- }
1419
-
1420
- var __defProp$5 = Object.defineProperty;
1421
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1422
- var __publicField$3 = (obj, key, value) => __defNormalProp$5(obj, key + "" , value);
1423
- class NetworkError extends Error {
1424
- constructor(url) {
1425
- super();
1426
- __publicField$3(this, "name", "NetworkError");
1427
- Object.setPrototypeOf(this, NetworkError.prototype);
1428
- this.message = `Unable to request ${url}.
1429
- Possibly invalid NGW URL entered or CORS not configured to get request from ${location.origin}`;
1430
- }
1431
- }
1432
-
1433
- let loadData;
1434
- {
1435
- loadData = (url, callback, options = {}, error, onCancel) => {
1436
- options.method = options.method || "GET";
1437
- const xhr = new XMLHttpRequest();
1438
- xhr.open(options.method || "GET", url, true);
1439
- if (options.responseType === "blob") {
1440
- xhr.responseType = options.responseType;
2028
+ if (typeof resource === "string") {
2029
+ return this._fetchResourceBy({ keyname: resource }, opt);
2030
+ } else if (typeof resource === "number") {
2031
+ return this._fetchResourceById(resource, opt);
2032
+ } else if (isObject(resource)) {
2033
+ return this._fetchResourceBy(resource, opt);
1441
2034
  }
1442
- const getResponseText = () => {
1443
- try {
1444
- return JSON.parse(xhr.responseText);
1445
- } catch (er) {
1446
- return xhr.responseText;
2035
+ return Promise.resolve(void 0);
2036
+ }
2037
+ getOneOrFail(resource, requestOptions) {
2038
+ return this.getOne(resource, requestOptions).then((res) => {
2039
+ if (res) {
2040
+ return res;
1447
2041
  }
1448
- };
1449
- const processingResponse = (forError = false) => {
1450
- const cb = forError ? error : callback;
1451
- if (options.responseType === "blob") {
1452
- cb(xhr.response);
1453
- } else {
1454
- if (xhr.responseText) {
1455
- cb(getResponseText());
2042
+ throw new ResourceNotFoundError();
2043
+ });
2044
+ }
2045
+ /**
2046
+ * A fast way to retrieve resource ID for any resource definition.
2047
+ * @param resource - Any available resource definition
2048
+ *
2049
+ * @remarks
2050
+ * There are situations when exactly the resource id is needed
2051
+ * (for example, to compose the correct request to the api)
2052
+ * then this method will come in handy to facilitate the extraction of the identifier
2053
+ * if the resource is specified through a keyname or other parameters.
2054
+ */
2055
+ getId(resource, requestOptions) {
2056
+ if (typeof resource === "number") {
2057
+ return Promise.resolve(resource);
2058
+ } else if (typeof resource === "string" || isObject(resource)) {
2059
+ return this.getOne(resource, requestOptions).then((res) => {
2060
+ if (res) {
2061
+ return res.resource.id;
2062
+ }
2063
+ });
2064
+ }
2065
+ return Promise.resolve(void 0);
2066
+ }
2067
+ /**
2068
+ * A fast way to retrieve resource ID for any resource definition.
2069
+ * @param resource - Any available resource definition
2070
+ *
2071
+ * @remarks
2072
+ * Similar with {@link NgwConnector.getResourceId | getResourceId} but rise error if resource is not exist.
2073
+ * To not make one more checks if the resource is definitely exists
2074
+ */
2075
+ getIdOrFail(resource, requestOptions) {
2076
+ return this.getId(resource, requestOptions).then((resp) => {
2077
+ if (resp === void 0) {
2078
+ throw new Error();
2079
+ }
2080
+ return resp;
2081
+ });
2082
+ }
2083
+ getMany(resource, requestOptions) {
2084
+ return this._resourceCacheFilter(resource).then((items) => {
2085
+ if (!items.length) {
2086
+ const query = {};
2087
+ if (resource.keyname) {
2088
+ query.keyname = resource.keyname;
1456
2089
  } else {
1457
- error({ message: "" });
2090
+ Object.assign(query, resourceToQuery(resource));
1458
2091
  }
2092
+ return this.connector.get("resource.search", requestOptions, __spreadValues$4({
2093
+ serialization: "full"
2094
+ }, query)).then((resources) => {
2095
+ if ((requestOptions == null ? void 0 : requestOptions.cache) && resources) {
2096
+ for (const x of resources) {
2097
+ this.cache.add("resource.item", Promise.resolve(x), {
2098
+ id: x.resource.id
2099
+ });
2100
+ }
2101
+ }
2102
+ return resources;
2103
+ });
1459
2104
  }
1460
- };
1461
- xhr.onload = () => {
1462
- if ([401, 403, 404, 422, 500].indexOf(xhr.status) !== -1) {
1463
- error(new NgwError(getResponseText()));
2105
+ return items;
2106
+ });
2107
+ }
2108
+ getParent(resource, requestOptions) {
2109
+ return this.getOne(resource, requestOptions).then((child) => {
2110
+ if (child) {
2111
+ return this.getOne(child.resource.parent.id, requestOptions);
1464
2112
  }
1465
- processingResponse();
1466
- };
1467
- xhr.onerror = (er) => {
1468
- if (xhr.status === 0) {
1469
- error(new NetworkError(url));
1470
- } else {
1471
- error(er);
2113
+ return Promise.resolve(void 0);
2114
+ });
2115
+ }
2116
+ getChildrenOf(resource, requestOptions) {
2117
+ return this.getIdOrFail(resource).then(
2118
+ (parent) => this._getChildrenOf(parent, requestOptions)
2119
+ );
2120
+ }
2121
+ update(resource, data) {
2122
+ return this.getId(resource).then((id) => {
2123
+ if (id !== void 0) {
2124
+ return this.connector.put("resource.item", { data }, { id });
1472
2125
  }
1473
- };
1474
- xhr.upload.onprogress = function(e) {
1475
- if (e.lengthComputable) {
1476
- const percentComplete = e.loaded / e.total * 100;
1477
- if (options.onProgress) {
1478
- options.onProgress(percentComplete, e);
1479
- }
2126
+ });
2127
+ }
2128
+ /**
2129
+ * Fast way to delete resource from NGW and clean cache.
2130
+ * @param resource - Resource definition
2131
+ */
2132
+ delete(resource) {
2133
+ return this.getId(resource).then((id) => {
2134
+ if (id !== void 0) {
2135
+ return this.connector.delete("resource.item", null, { id }).then(() => {
2136
+ this._cleanResourceItemCache(id);
2137
+ return void 0;
2138
+ });
1480
2139
  }
1481
- };
1482
- const headers = options.headers;
1483
- if (headers) {
1484
- for (const h in headers) {
1485
- const header = headers[h];
1486
- if (typeof header === "string") {
1487
- xhr.setRequestHeader(h, header);
2140
+ });
2141
+ }
2142
+ _getChildrenOf(parent, requestOptions, _items = []) {
2143
+ return this.connector.get("resource.collection", requestOptions, {
2144
+ parent
2145
+ }).then((items) => {
2146
+ const recursivePromises = [];
2147
+ for (const item of items) {
2148
+ if (requestOptions == null ? void 0 : requestOptions.cache) {
2149
+ this.cache.add("resource.item", Promise.resolve(item), {
2150
+ id: item.resource.id
2151
+ });
2152
+ }
2153
+ _items.push(item);
2154
+ if ((requestOptions == null ? void 0 : requestOptions.recursive) && item.resource.children) {
2155
+ recursivePromises.push(
2156
+ this._getChildrenOf(item.resource.id, requestOptions, _items)
2157
+ );
1488
2158
  }
1489
2159
  }
1490
- }
1491
- if (options.withCredentials !== void 0) {
1492
- xhr.withCredentials = options.withCredentials;
1493
- }
1494
- let data;
1495
- if (options.file) {
1496
- data = new FormData();
1497
- data.append("file", options.file);
1498
- if (options.data) {
1499
- for (const d in options.data) {
1500
- data.append(d, data[d]);
2160
+ if (recursivePromises.length) {
2161
+ return Promise.all(recursivePromises).then(() => {
2162
+ return _items;
2163
+ });
2164
+ }
2165
+ return _items;
2166
+ });
2167
+ }
2168
+ _cleanResourceItemCache(id) {
2169
+ return __async$3(this, null, function* () {
2170
+ var _a;
2171
+ const all = this.cache.all();
2172
+ const toDelete = [];
2173
+ for (const c of all) {
2174
+ const cid = (_a = c.props) == null ? void 0 : _a.id;
2175
+ if (["resource.item", "resource"].includes(c.key) && cid !== void 0) {
2176
+ if (typeof cid === "number") {
2177
+ if (cid === id) {
2178
+ toDelete.push(c);
2179
+ }
2180
+ } else {
2181
+ const rid = yield this.getId(cid);
2182
+ if (rid === id) {
2183
+ toDelete.push(c);
2184
+ }
2185
+ }
1501
2186
  }
1502
2187
  }
1503
- } else {
1504
- data = options.data ? typeof options.data === "string" ? options.data : JSON.stringify(options.data) : null;
1505
- }
1506
- if (onCancel) {
1507
- onCancel(() => {
1508
- xhr.abort();
1509
- });
1510
- }
1511
- xhr.send(data);
1512
- };
2188
+ for (const d of toDelete) {
2189
+ this.cache.delete(d);
2190
+ }
2191
+ });
2192
+ }
2193
+ _fetchResourceById(id, requestOptions) {
2194
+ return this.connector.get("resource.item", requestOptions, { id });
2195
+ }
2196
+ _fetchResourceBy(resource, requestOptions) {
2197
+ return this.getMany(resource, requestOptions).then((resources) => {
2198
+ return resources[0];
2199
+ });
2200
+ }
2201
+ _resourceCacheFilter(resource) {
2202
+ return Promise.all(this.cache.matchAll("resource.item")).then(
2203
+ (resources) => {
2204
+ const items = [];
2205
+ resources.filter((x) => {
2206
+ if (x) {
2207
+ if (resource.keyname && x.resource.keyname) {
2208
+ return resource.keyname === x.resource.keyname;
2209
+ }
2210
+ if (defined(resource.id) && defined(x.resource.id)) {
2211
+ return resource.id === x.resource.id;
2212
+ }
2213
+ return resourceCompare(resource, x.resource);
2214
+ }
2215
+ });
2216
+ return items;
2217
+ }
2218
+ );
2219
+ }
1513
2220
  }
1514
2221
 
1515
- var __defProp$4 = Object.defineProperty;
1516
- var __defProps$2 = Object.defineProperties;
1517
- var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
2222
+ var __defProp$5 = Object.defineProperty;
1518
2223
  var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
1519
2224
  var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
1520
2225
  var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
1521
- var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2226
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1522
2227
  var __spreadValues$3 = (a, b) => {
1523
2228
  for (var prop in b || (b = {}))
1524
2229
  if (__hasOwnProp$3.call(b, prop))
1525
- __defNormalProp$4(a, prop, b[prop]);
2230
+ __defNormalProp$5(a, prop, b[prop]);
1526
2231
  if (__getOwnPropSymbols$3)
1527
2232
  for (var prop of __getOwnPropSymbols$3(b)) {
1528
2233
  if (__propIsEnum$3.call(b, prop))
1529
- __defNormalProp$4(a, prop, b[prop]);
2234
+ __defNormalProp$5(a, prop, b[prop]);
1530
2235
  }
1531
2236
  return a;
1532
2237
  };
1533
- var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
1534
- var __objRest = (source, exclude) => {
1535
- var target = {};
1536
- for (var prop in source)
1537
- if (__hasOwnProp$3.call(source, prop) && exclude.indexOf(prop) < 0)
1538
- target[prop] = source[prop];
1539
- if (source != null && __getOwnPropSymbols$3)
1540
- for (var prop of __getOwnPropSymbols$3(source)) {
1541
- if (exclude.indexOf(prop) < 0 && __propIsEnum$3.call(source, prop))
1542
- target[prop] = source[prop];
1543
- }
1544
- return target;
1545
- };
1546
- var __publicField$2 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
1547
2238
  var __async$2 = (__this, __arguments, generator) => {
1548
2239
  return new Promise((resolve, reject) => {
1549
2240
  var fulfilled = (value) => {
@@ -1564,172 +2255,76 @@ var Geocoder = (function (exports) {
1564
2255
  step((generator = generator.apply(__this, __arguments)).next());
1565
2256
  });
1566
2257
  };
1567
- let ID = 0;
1568
- let REQUEST_ID = 0;
1569
- class NgwConnector {
1570
- constructor(options) {
1571
- this.options = options;
1572
- __publicField$2(this, "id", ID++);
1573
- __publicField$2(this, "emitter", new EventEmitter());
1574
- __publicField$2(this, "user");
1575
- __publicField$2(this, "resources");
1576
- __publicField$2(this, "cache");
1577
- __publicField$2(this, "withCredentials");
1578
- __publicField$2(this, "client", `NextGIS-NGW-Connector/${pkg.version}`);
1579
- __publicField$2(this, "routeStr", "/api/component/pyramid/route");
1580
- __publicField$2(this, "activeRequests", {});
1581
- __publicField$2(this, "requestTransform");
1582
- const exist = findConnector(options);
1583
- this.cache = new Cache({ namespace: options.cacheId });
1584
- if (exist) {
1585
- return exist;
1586
- } else {
1587
- const { route, requestTransform, withCredentials } = this.options;
1588
- if (route) {
1589
- this.routeStr = route;
1590
- }
1591
- if (requestTransform) {
1592
- this.requestTransform = requestTransform;
1593
- }
1594
- if (withCredentials !== void 0) {
1595
- this.withCredentials = withCredentials;
1596
- }
1597
- this.resources = new ResourcesControl({
1598
- connector: this,
1599
- cacheId: options.cacheId
1600
- });
1601
- addConnector(this);
1602
- }
1603
- }
1604
- static create(options) {
1605
- return new this(options);
1606
- }
1607
- /**
1608
- * Clear the cache.
1609
- */
1610
- clearCache() {
1611
- this.cache.clean();
1612
- this.resources.cache.clean();
1613
- }
1614
- setRequestTransform(requestTransform) {
1615
- this.requestTransform = requestTransform;
1616
- }
1617
- /**
1618
- * Fast way to specify the connection address to NextGIS Web.
1619
- * The current connection will be severed.
1620
- * @param baseUrl - NGW url
1621
- */
1622
- setNgw(baseUrl) {
1623
- this.logout();
1624
- this.options.baseUrl = baseUrl;
1625
- addConnector(this);
1626
- }
1627
- /**
1628
- * Establishing a connection with NextGIS Web to fulfill all other requests.
1629
- * @remarks
1630
- * This method need not be called manually as it is used when forming a request in {@link apiRequest | apiRequest}.
1631
- * Can be used to check connection.
1632
- * @example
1633
- * ```javascript
1634
- * const connector = new NgwConnector({baseUrl: 'https://demo.nextgis.com'});
1635
- * connector.connect()
1636
- * .then(() => console.log('Ok'))
1637
- * .catch((er) => console.log('Connection problem', er));
1638
- * ```
1639
- */
1640
- connect() {
1641
- return __async$2(this, null, function* () {
1642
- const auth = this.options.auth;
1643
- if (auth) {
1644
- const { login, password } = auth;
1645
- if (login && password) {
1646
- yield this._login({ login, password });
2258
+ function apiRequest(opt) {
2259
+ return __async$2(this, null, function* () {
2260
+ const { params, name, connector, requestOptions } = opt;
2261
+ const apiItems = yield connector.connect();
2262
+ let apiItem = apiItems && apiItems[name];
2263
+ if (apiItem) {
2264
+ apiItem = [...apiItem];
2265
+ let url = apiItem.shift();
2266
+ if (apiItem.length) {
2267
+ const replaceParams = {};
2268
+ for (let fry = 0; fry < apiItem.length; fry++) {
2269
+ const arg = apiItem[fry];
2270
+ replaceParams[fry] = `{${arg}}`;
2271
+ if (params[arg] === void 0) {
2272
+ throw new Error(`\`${arg}\` URL API argument is not specified`);
2273
+ }
2274
+ }
2275
+ if (url) {
2276
+ url = template(url, replaceParams);
1647
2277
  }
1648
2278
  }
1649
- const routeUrl = `${this.routeStr}?client=${this.client}`;
1650
- return yield this.makeQuery(
1651
- routeUrl,
1652
- {},
1653
- {
1654
- cacheName: "route",
1655
- cache: true,
1656
- cacheProps: {
1657
- id: this.id,
1658
- auth,
1659
- baseUrl: this.options.baseUrl
2279
+ if (params) {
2280
+ const paramArray = [];
2281
+ const paramList = params.paramList;
2282
+ if (Array.isArray(paramList)) {
2283
+ paramList.forEach(([key, value]) => {
2284
+ paramArray.push(`${key}=${value}`);
2285
+ });
2286
+ }
2287
+ for (const p in params) {
2288
+ if (apiItem.indexOf(p) === -1) {
2289
+ paramArray.push(`${p}=${params[p]}`);
1660
2290
  }
1661
2291
  }
1662
- );
1663
- });
1664
- }
1665
- /**
1666
- * Quick way to change NextGIS Web user.
1667
- * @param credentials - New user credentials
1668
- */
1669
- login(credentials, options) {
1670
- this.logout();
1671
- addConnector(this);
1672
- return this._login(credentials, options);
1673
- }
1674
- /**
1675
- * Disconnecting a user. Aborting all current requests
1676
- */
1677
- logout() {
1678
- this.abort();
1679
- removeConnector(this);
1680
- this.options.auth = void 0;
1681
- this.user = void 0;
1682
- this.clearCache();
1683
- this.emitter.emit("logout");
1684
- }
1685
- getUserInfo(credentials, options) {
1686
- return __async$2(this, null, function* () {
1687
- if (this.user && this.user.id) {
1688
- return this.user;
2292
+ if (paramArray.length) {
2293
+ url = `${url}?${paramArray.join("&")}`;
2294
+ }
1689
2295
  }
1690
- if (credentials) {
1691
- this.options.auth = credentials;
2296
+ if (url) {
2297
+ return connector.makeQuery(url, params, __spreadValues$3({
2298
+ cacheName: name
2299
+ }, requestOptions));
2300
+ } else {
2301
+ throw new Error("Request URL is not set");
1692
2302
  }
1693
- const options_ = __spreadValues$3({
1694
- headers: this.getAuthorizationHeaders(credentials)
1695
- }, options);
1696
- return this.makeQuery(
1697
- "/api/component/auth/current_user",
1698
- {},
1699
- options_
1700
- );
2303
+ } else {
2304
+ return void 0;
2305
+ }
2306
+ });
2307
+ }
2308
+
2309
+ var __defProp$4 = Object.defineProperty;
2310
+ var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2311
+ var __publicField$2 = (obj, key, value) => __defNormalProp$4(obj, key + "" , value);
2312
+ class NgwConnectorExtended extends NgwConnector {
2313
+ constructor(options) {
2314
+ super(options);
2315
+ this.options = options;
2316
+ __publicField$2(this, "resources");
2317
+ this.resources = new ResourcesControl({
2318
+ connector: this,
2319
+ cacheId: options.cacheId
1701
2320
  });
1702
2321
  }
1703
2322
  /**
1704
- * Obtaining the required Headers for authentication of requests in the NGW.
2323
+ * Clear the cache.
1705
2324
  */
1706
- getAuthorizationHeaders(credentials) {
1707
- const client = this.makeClientId(credentials);
1708
- if (client) {
1709
- return {
1710
- Authorization: `Basic ${client}`
1711
- };
1712
- }
1713
- }
1714
- makeClientId(credentials) {
1715
- credentials = credentials || this.options.auth;
1716
- if (credentials) {
1717
- const { login, password } = credentials;
1718
- const encodedStr = [login, password].map(encodeURIComponent).join(":");
1719
- {
1720
- return window.btoa(encodedStr);
1721
- }
1722
- }
1723
- }
1724
- /** Stop all api requests */
1725
- abort() {
1726
- for (const abortController of Object.values(this.activeRequests)) {
1727
- abortController.abort();
1728
- }
1729
- this.activeRequests = {};
1730
- }
1731
- getActiveApiRequests() {
1732
- return __spreadValues$3({}, this.activeRequests);
2325
+ clearCache() {
2326
+ super.clearCache();
2327
+ this.resources.cache.clean();
1733
2328
  }
1734
2329
  /**
1735
2330
  * Send request to NGW api router.
@@ -1848,75 +2443,6 @@ var Geocoder = (function (exports) {
1848
2443
  options
1849
2444
  );
1850
2445
  }
1851
- /**
1852
- * Send request to NGW.
1853
- * @param url - URL address to NGW
1854
- * @param params - Query params
1855
- * @param options - Request options
1856
- */
1857
- makeQuery(_0, _1) {
1858
- return __async$2(this, arguments, function* (url, params, options = {}) {
1859
- var _b;
1860
- url = (this.options.baseUrl ? this.options.baseUrl : "") + url;
1861
- if (!url) {
1862
- throw new Error("Empty `url` not allowed");
1863
- }
1864
- if (params) {
1865
- const _a = params, restParams = __objRest(_a, ["paramList"]);
1866
- url = template(url, restParams);
1867
- }
1868
- url = encodeURI(fixUrlStr(url));
1869
- options = __spreadValues$3({ withCredentials: this.withCredentials }, options);
1870
- const {
1871
- cache,
1872
- signal: externalSignal,
1873
- method = "GET",
1874
- headers,
1875
- cacheName,
1876
- cacheProps,
1877
- responseType,
1878
- withCredentials
1879
- } = options;
1880
- const internalAbortController = new AbortController();
1881
- const internalSignal = internalAbortController.signal;
1882
- if (externalSignal) {
1883
- if (externalSignal.aborted) {
1884
- throw new AbortError();
1885
- }
1886
- externalSignal.addEventListener("abort", () => {
1887
- internalAbortController.abort();
1888
- });
1889
- }
1890
- options.signal = internalSignal;
1891
- const createPromise = () => __async$2(this, null, function* () {
1892
- const id = REQUEST_ID++;
1893
- this.activeRequests[id] = internalAbortController;
1894
- try {
1895
- return this._loadData(url, options);
1896
- } finally {
1897
- this._cleanActiveRequest(id);
1898
- }
1899
- });
1900
- if (cache && method === "GET") {
1901
- const cacheOptions = cacheProps ? cacheProps : __spreadProps$2(__spreadValues$3({}, objectRemoveEmpty({
1902
- headers,
1903
- withCredentials,
1904
- responseType,
1905
- baseUrl: this.options.baseUrl,
1906
- userId: (_b = this.user) == null ? void 0 : _b.id
1907
- })), {
1908
- params
1909
- });
1910
- return this.cache.add(
1911
- cacheName || url,
1912
- createPromise,
1913
- cacheOptions,
1914
- false
1915
- );
1916
- }
1917
- return createPromise();
1918
- });
1919
- }
1920
2446
  // -------------------------------------------------------------------------
1921
2447
  // Resource Methods
1922
2448
  // -------------------------------------------------------------------------
@@ -1992,78 +2518,7 @@ var Geocoder = (function (exports) {
1992
2518
  deleteResource(resource) {
1993
2519
  return this.resources.delete(resource);
1994
2520
  }
1995
- /**
1996
- * @internal
1997
- */
1998
- _loadData(url, options) {
1999
- options.responseType = options.responseType || "json";
2000
- return new Promise((resolve, reject) => {
2001
- var _a;
2002
- if (this.user) {
2003
- options = options || {};
2004
- options.headers = __spreadValues$3(__spreadValues$3({}, this.getAuthorizationHeaders()), options.headers);
2005
- }
2006
- if (this.requestTransform) {
2007
- const [transUrl, transOptions] = this.requestTransform(url, options);
2008
- url = transUrl;
2009
- options = transOptions;
2010
- }
2011
- let runOnAbort = void 0;
2012
- loadData(url, resolve, options, reject, (handler) => {
2013
- runOnAbort = handler;
2014
- });
2015
- (_a = options.signal) == null ? void 0 : _a.addEventListener("abort", () => {
2016
- if (runOnAbort !== void 0) {
2017
- runOnAbort();
2018
- }
2019
- reject(new AbortError());
2020
- });
2021
- }).catch((httpError) => {
2022
- if (httpError.name !== "AbortError") {
2023
- {
2024
- console.warn("DEV WARN", httpError);
2025
- }
2026
- const er = this._handleHttpError(httpError);
2027
- if (er) {
2028
- throw er;
2029
- }
2030
- }
2031
- throw httpError;
2032
- });
2033
- }
2034
- _login(credentials, options) {
2035
- return __async$2(this, null, function* () {
2036
- try {
2037
- const data = yield this.getUserInfo(credentials, options);
2038
- this.user = data;
2039
- this.emitter.emit("login", data);
2040
- return data;
2041
- } catch (er) {
2042
- this.emitter.emit("login:error", er);
2043
- throw er;
2044
- }
2045
- });
2046
- }
2047
- _cleanActiveRequest(requestId) {
2048
- delete this.activeRequests[requestId];
2049
- }
2050
- _handleHttpError(er) {
2051
- if (er) {
2052
- if (er instanceof NgwError) {
2053
- if (er.exception === "nextgisweb.resource.exception.ResourceNotFound") {
2054
- throw new ResourceNotFoundError(er);
2055
- } else if (er.exception === "nextgisweb.core.exception.InsufficientPermissions") {
2056
- throw new InsufficientPermissionsError(er);
2057
- }
2058
- }
2059
- }
2060
- return er;
2061
- }
2062
2521
  }
2063
- __publicField$2(NgwConnector, "errors", {
2064
- NgwError,
2065
- ResourceNotFoundError
2066
- });
2067
2522
 
2068
2523
  function reEscape(s) {
2069
2524
  return s.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&");
@@ -2499,7 +2954,7 @@ var Geocoder = (function (exports) {
2499
2954
  "The `searchUrl` of `connectorOptions.baseUrl` are required"
2500
2955
  );
2501
2956
  }
2502
- this.connector = options.connector || new NgwConnector(__spreadValues({
2957
+ this.connector = options.connector || new NgwConnectorExtended(__spreadValues({
2503
2958
  baseUrl: this.searchUrl
2504
2959
  }, options.connectorOptions));
2505
2960
  this.searchResources = options.searchResources;