@nextgis/geocoder 3.0.0-alpha.4 → 3.0.0-alpha.6

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