@nextgis/ngw-connector 3.0.0-alpha.2 → 3.0.0-alpha.22

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,11 +1,111 @@
1
- /** Bundle of @nextgis/ngw-connector; version: 3.0.0-alpha.2; author: NextGIS */
2
- import { EventEmitter } from 'events';
1
+ /** Bundle of @nextgis/ngw-connector; version: 3.0.0-alpha.20; author: NextGIS */
2
+ import { isObject as isObject$1, objectRemoveEmpty, fixUrlStr, objectDeepEqual, defined } from '@nextgis/utils';
3
3
  import Cache from '@nextgis/cache';
4
- import { objectDeepEqual, defined, objectRemoveEmpty, fixUrlStr } from '@nextgis/utils';
4
+ import { EventEmitter } from 'events';
5
+
6
+ const templateRe = /\{ *([\w_-]+) *\}/g;
7
+ function template(str, data) {
8
+ return str.replace(templateRe, (s, key) => {
9
+ let value = data[key];
10
+ if (value === void 0) {
11
+ throw new Error("No value provided for letiable " + s);
12
+ } else if (typeof value === "function") {
13
+ value = value(data);
14
+ }
15
+ return value;
16
+ });
17
+ }
18
+
19
+ var __defProp$b = Object.defineProperty;
20
+ var __getOwnPropSymbols$4 = Object.getOwnPropertySymbols;
21
+ var __hasOwnProp$4 = Object.prototype.hasOwnProperty;
22
+ var __propIsEnum$4 = Object.prototype.propertyIsEnumerable;
23
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
24
+ var __spreadValues$4 = (a, b) => {
25
+ for (var prop in b || (b = {}))
26
+ if (__hasOwnProp$4.call(b, prop))
27
+ __defNormalProp$b(a, prop, b[prop]);
28
+ if (__getOwnPropSymbols$4)
29
+ for (var prop of __getOwnPropSymbols$4(b)) {
30
+ if (__propIsEnum$4.call(b, prop))
31
+ __defNormalProp$b(a, prop, b[prop]);
32
+ }
33
+ return a;
34
+ };
35
+ var __async$4 = (__this, __arguments, generator) => {
36
+ return new Promise((resolve, reject) => {
37
+ var fulfilled = (value) => {
38
+ try {
39
+ step(generator.next(value));
40
+ } catch (e) {
41
+ reject(e);
42
+ }
43
+ };
44
+ var rejected = (value) => {
45
+ try {
46
+ step(generator.throw(value));
47
+ } catch (e) {
48
+ reject(e);
49
+ }
50
+ };
51
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
52
+ step((generator = generator.apply(__this, __arguments)).next());
53
+ });
54
+ };
55
+ function apiRequest(opt) {
56
+ return __async$4(this, null, function* () {
57
+ const { params, name, connector, requestOptions } = opt;
58
+ const apiItems = yield connector.connect();
59
+ let apiItem = apiItems && apiItems[name];
60
+ if (apiItem) {
61
+ apiItem = [...apiItem];
62
+ let url = apiItem.shift();
63
+ if (apiItem.length) {
64
+ const replaceParams = {};
65
+ for (let fry = 0; fry < apiItem.length; fry++) {
66
+ const arg = apiItem[fry];
67
+ replaceParams[fry] = `{${arg}}`;
68
+ if (params[arg] === void 0) {
69
+ throw new Error(`\`${arg}\` URL API argument is not specified`);
70
+ }
71
+ }
72
+ if (url) {
73
+ url = template(url, replaceParams);
74
+ }
75
+ }
76
+ if (params) {
77
+ const paramArray = [];
78
+ const paramList = params.paramList;
79
+ if (Array.isArray(paramList)) {
80
+ paramList.forEach(([key, value]) => {
81
+ paramArray.push(`${key}=${value}`);
82
+ });
83
+ }
84
+ for (const p in params) {
85
+ if (apiItem.indexOf(p) === -1) {
86
+ paramArray.push(`${p}=${params[p]}`);
87
+ }
88
+ }
89
+ if (paramArray.length) {
90
+ url = `${url}?${paramArray.join("&")}`;
91
+ }
92
+ }
93
+ if (url) {
94
+ return connector.makeQuery(url, params, __spreadValues$4({
95
+ cacheName: name
96
+ }, requestOptions));
97
+ } else {
98
+ throw new Error("Request URL is not set");
99
+ }
100
+ } else {
101
+ return void 0;
102
+ }
103
+ });
104
+ }
5
105
 
6
106
  var pkg = {
7
107
  name: "@nextgis/ngw-connector",
8
- version: "3.0.0-alpha.2",
108
+ version: "3.0.0-alpha.20",
9
109
  _priority: 12,
10
110
  description: "A lightweight HTTP client optimized for use with NextGIS Web API",
11
111
  main: "index.js",
@@ -14,15 +114,15 @@ var pkg = {
14
114
  jsdelivr: "lib/ngw-connector.global.prod.js",
15
115
  types: "lib/index.d.ts",
16
116
  dependencies: {
17
- "@nextgis/cache": "^3.0.0-alpha.1",
18
- "@nextgis/cancelable-promise": "^3.0.0-alpha.1",
19
- "@nextgis/utils": "^3.0.0-alpha.1",
117
+ "@nextgis/cache": "3.0.0-alpha.17",
118
+ "@nextgis/cancelable-promise": "3.0.0-alpha.17",
119
+ "@nextgis/utils": "3.0.0-alpha.17",
20
120
  "@types/events": "^3.0.0",
21
121
  events: "*",
22
122
  "form-data": "^4.0.0"
23
123
  },
24
124
  devDependencies: {
25
- "@nextgis/build-tools": "^3.0.0-alpha.1"
125
+ "@nextgis/build-tools": "3.0.0-alpha.17"
26
126
  },
27
127
  scripts: {
28
128
  clean: "rimraf ./lib",
@@ -56,31 +156,111 @@ var pkg = {
56
156
  type: "git",
57
157
  url: "git://github.com/nextgis/nextgis_frontend.git"
58
158
  },
159
+ engines: {
160
+ node: ">=18.20.4"
161
+ },
59
162
  gitHead: "edc68033f914f6c95c4125b9738bba6d36e990b4"
60
163
  };
61
164
 
62
- var __defProp$6 = Object.defineProperty;
63
- var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
64
- var __publicField$5 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
165
+ class AbortError extends Error {
166
+ constructor(message = "AbortError") {
167
+ super(message);
168
+ this.name = "AbortError";
169
+ }
170
+ }
171
+
172
+ var __defProp$a = Object.defineProperty;
173
+ var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
174
+ var __publicField$8 = (obj, key, value) => __defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
65
175
  class NgwError extends Error {
66
176
  constructor(er) {
67
177
  super();
68
- __publicField$5(this, "name", "NgwError");
69
- __publicField$5(this, "title");
70
- __publicField$5(this, "message");
71
- __publicField$5(this, "detail");
72
- __publicField$5(this, "exception");
73
- __publicField$5(this, "status_code");
74
- __publicField$5(this, "data");
75
- __publicField$5(this, "guru_meditation");
178
+ __publicField$8(this, "name", "NgwError");
179
+ __publicField$8(this, "title");
180
+ __publicField$8(this, "message");
181
+ __publicField$8(this, "detail");
182
+ __publicField$8(this, "exception");
183
+ __publicField$8(this, "status_code");
184
+ __publicField$8(this, "data");
185
+ __publicField$8(this, "guru_meditation");
76
186
  Object.assign(this, er);
77
187
  Object.setPrototypeOf(this, NgwError.prototype);
78
188
  }
79
189
  }
80
190
 
81
- var __defProp$5 = Object.defineProperty;
82
- var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
83
- var __publicField$4 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
191
+ var __defProp$9 = Object.defineProperty;
192
+ var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
193
+ var __publicField$7 = (obj, key, value) => __defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
194
+ class InsufficientPermissionsError extends NgwError {
195
+ constructor(obj) {
196
+ super(obj);
197
+ __publicField$7(this, "name", "InsufficientPermissionsError");
198
+ __publicField$7(this, "exception", "nextgisweb.core.exception.InsufficientPermissions");
199
+ Object.setPrototypeOf(this, InsufficientPermissionsError.prototype);
200
+ }
201
+ }
202
+
203
+ var __defProp$8 = Object.defineProperty;
204
+ var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
205
+ var __publicField$6 = (obj, key, value) => __defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
206
+ let NetworksResponseError$1 = class NetworksResponseError extends NgwError {
207
+ constructor(obj) {
208
+ super(obj);
209
+ __publicField$6(this, "message", "There is no response from the server or problem connecting to server.");
210
+ __publicField$6(this, "title", "Network error");
211
+ __publicField$6(this, "detail", "Check network connectivity and try again later.");
212
+ Object.setPrototypeOf(this, NetworksResponseError.prototype);
213
+ }
214
+ };
215
+
216
+ function extractError(error) {
217
+ if (isObject$1(error)) {
218
+ if (error.name && error.message && error.title) {
219
+ return {
220
+ title: error.title,
221
+ message: error.message,
222
+ detail: error.detail || null,
223
+ data: error.data && error.data.data ? error.data.data : null
224
+ };
225
+ } else if (error.exception) {
226
+ if (error.status === void 0 || error.status === 0 || error.data === void 0) {
227
+ return new NetworksResponseError$1({
228
+ title: error.title,
229
+ status_code: error.status_code,
230
+ exception: error.exception
231
+ });
232
+ }
233
+ }
234
+ return {
235
+ title: typeof error.title === "string" ? error.title : "Unexpected error",
236
+ message: typeof error.message === "string" ? error.message : "Something went wrong."
237
+ };
238
+ }
239
+ }
240
+
241
+ function isError(error) {
242
+ if (isObject$1(error)) {
243
+ return error.status_code && error.exception && error.title;
244
+ }
245
+ return false;
246
+ }
247
+
248
+ var __defProp$7 = Object.defineProperty;
249
+ var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
250
+ var __publicField$5 = (obj, key, value) => __defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
251
+ class NetworkError extends Error {
252
+ constructor(url) {
253
+ super();
254
+ __publicField$5(this, "name", "NetworkError");
255
+ Object.setPrototypeOf(this, NetworkError.prototype);
256
+ this.message = `Unable to request ${url}.
257
+ Possibly invalid NGW URL entered or CORS not configured to get request from ${location.origin}`;
258
+ }
259
+ }
260
+
261
+ var __defProp$6 = Object.defineProperty;
262
+ var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
263
+ var __publicField$4 = (obj, key, value) => __defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
84
264
  class ResourceNotFoundError extends NgwError {
85
265
  constructor(obj) {
86
266
  super(obj);
@@ -90,53 +270,111 @@ class ResourceNotFoundError extends NgwError {
90
270
  }
91
271
  }
92
272
 
93
- function isObject(val) {
94
- return Object.prototype.toString.call(val) === "[object Object]";
95
- }
273
+ var errors = /*#__PURE__*/Object.freeze({
274
+ __proto__: null,
275
+ AbortError: AbortError,
276
+ InsufficientPermissionsError: InsufficientPermissionsError,
277
+ NetworkError: NetworkError,
278
+ NetworksResponseError: NetworksResponseError$1,
279
+ NgwError: NgwError,
280
+ ResourceNotFoundError: ResourceNotFoundError,
281
+ extractError: extractError,
282
+ isError: isError
283
+ });
96
284
 
97
- function resourceCompare(res1, res2) {
98
- return objectDeepEqual(res1, res2);
285
+ var __defProp$5 = Object.defineProperty;
286
+ var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
287
+ var __publicField$3 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
288
+ class BaseAPIError extends Error {
289
+ constructor(message) {
290
+ super(message || "Something went wrong.");
291
+ __publicField$3(this, "title");
292
+ this.name = "BaseAPIError";
293
+ this.title = "Unknown API error";
294
+ if (Error.captureStackTrace) {
295
+ Error.captureStackTrace(this, BaseAPIError);
296
+ }
297
+ }
99
298
  }
100
-
101
- const exclude = ["description"];
102
- function resourceToQuery(resource, prefix = "") {
103
- prefix = prefix ? prefix + "__" : "";
104
- const query = {};
105
- for (const [key, value] of Object.entries(resource)) {
106
- if (exclude.indexOf(key) === -1) {
107
- if (isObject(value)) {
108
- if (key === "owner_user") {
109
- const children = resourceToQuery(value, key);
110
- Object.assign(query, children);
111
- } else if (key === "parent" && "id" in value) {
112
- query.parent_id = value.id;
113
- }
114
- } else if (defined(value)) {
115
- query[prefix + key] = value;
116
- }
299
+ class NetworksResponseError extends BaseAPIError {
300
+ // prettier-ignore
301
+ constructor(message) {
302
+ super(message || "There is no response from the server or problem connecting to server.");
303
+ __publicField$3(this, "detail");
304
+ this.title = "Network error";
305
+ this.detail = "Check network connectivity and try again later.";
306
+ }
307
+ }
308
+ class InvalidResponseError extends BaseAPIError {
309
+ constructor(message) {
310
+ super(message || "Something went wrong.");
311
+ this.title = "Unexpected server response";
312
+ }
313
+ }
314
+ class ServerResponseError extends BaseAPIError {
315
+ constructor(data) {
316
+ super(data.message);
317
+ __publicField$3(this, "detail");
318
+ __publicField$3(this, "data");
319
+ this.title = data.title || this.title;
320
+ this.detail = data.detail || null;
321
+ this.data = data;
322
+ }
323
+ }
324
+ class LunkwillError extends Error {
325
+ // prettier-ignore
326
+ constructor(message, data = {}) {
327
+ super(message || "Unexpected error while processing long-running request.");
328
+ __publicField$3(this, "title");
329
+ __publicField$3(this, "data");
330
+ this.name = "LunkwillError";
331
+ this.title = "Long-running request error";
332
+ this.data = data;
333
+ if (Error.captureStackTrace) {
334
+ Error.captureStackTrace(this, LunkwillError);
117
335
  }
118
336
  }
119
- return query;
337
+ }
338
+ class LunkwillRequestCancelled extends LunkwillError {
339
+ constructor(data) {
340
+ super("Long-running request was cancelled.", data);
341
+ }
342
+ }
343
+ class LunkwillRequestFailed extends LunkwillError {
344
+ constructor(data) {
345
+ super(void 0, data);
346
+ }
120
347
  }
121
348
 
122
349
  var __defProp$4 = Object.defineProperty;
123
- var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
124
- var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
125
- var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
350
+ var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
351
+ var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
352
+ var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
126
353
  var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
127
- var __spreadValues$2 = (a, b) => {
354
+ var __spreadValues$3 = (a, b) => {
128
355
  for (var prop in b || (b = {}))
129
- if (__hasOwnProp$2.call(b, prop))
356
+ if (__hasOwnProp$3.call(b, prop))
130
357
  __defNormalProp$4(a, prop, b[prop]);
131
- if (__getOwnPropSymbols$2)
132
- for (var prop of __getOwnPropSymbols$2(b)) {
133
- if (__propIsEnum$2.call(b, prop))
358
+ if (__getOwnPropSymbols$3)
359
+ for (var prop of __getOwnPropSymbols$3(b)) {
360
+ if (__propIsEnum$3.call(b, prop))
134
361
  __defNormalProp$4(a, prop, b[prop]);
135
362
  }
136
363
  return a;
137
364
  };
138
- var __publicField$3 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
139
- var __async$2 = (__this, __arguments, generator) => {
365
+ var __objRest$2 = (source, exclude) => {
366
+ var target = {};
367
+ for (var prop in source)
368
+ if (__hasOwnProp$3.call(source, prop) && exclude.indexOf(prop) < 0)
369
+ target[prop] = source[prop];
370
+ if (source != null && __getOwnPropSymbols$3)
371
+ for (var prop of __getOwnPropSymbols$3(source)) {
372
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$3.call(source, prop))
373
+ target[prop] = source[prop];
374
+ }
375
+ return target;
376
+ };
377
+ var __async$3 = (__this, __arguments, generator) => {
140
378
  return new Promise((resolve, reject) => {
141
379
  var fulfilled = (value) => {
142
380
  try {
@@ -156,307 +394,251 @@ var __async$2 = (__this, __arguments, generator) => {
156
394
  step((generator = generator.apply(__this, __arguments)).next());
157
395
  });
158
396
  };
159
- class ResourcesControl {
160
- constructor({
161
- connector,
162
- cacheId
163
- }) {
164
- __publicField$3(this, "cache");
165
- __publicField$3(this, "connector");
166
- this.connector = connector;
167
- this.cache = new Cache({ namespace: cacheId });
168
- }
169
- // -------------------------------------------------------------------------
170
- // Resource Methods
171
- // -------------------------------------------------------------------------
172
- /**
173
- * Receive resource from NGW by id, keyname or search-object parameter.
174
- * @param resource - Resource id, keyname or search-object
175
- *
176
- * @remarks
177
- * Fetching resource would be cached to speed up next call
178
- */
179
- getOne(resource, requestOptions) {
180
- const opt = __spreadValues$2({}, requestOptions);
181
- if (typeof resource === "string") ; else if (typeof resource === "number") ; else if (isObject(resource)) {
182
- if (resource.id !== void 0) {
183
- resource.id;
184
- } else {
185
- if (resource.keyname) {
186
- resource.keyname;
187
- }
188
- if (resource.display_name) {
189
- resource.display_name;
190
- }
397
+ function lunkwillCheckResponse(lwResp) {
398
+ const ct = lwResp.headers.get("content-type");
399
+ return ct !== void 0 && ct !== null && ct.includes("application/vnd.lunkwill.request-summary+json");
400
+ }
401
+ function responseJson(response) {
402
+ return __async$3(this, null, function* () {
403
+ try {
404
+ return response.json();
405
+ } catch (e) {
406
+ throw new Error();
407
+ }
408
+ });
409
+ }
410
+ function lunkwillResponseUrl(lwResp) {
411
+ return __async$3(this, null, function* () {
412
+ const lwData = yield responseJson(lwResp);
413
+ let delay = lwData.delay_ms;
414
+ const retry = lwData.retry_ms !== void 0 ? lwData.retry_ms : 2e3;
415
+ const sum = `/api/lunkwill/${lwData.id}/summary`;
416
+ const res = `/api/lunkwill/${lwData.id}/response`;
417
+ const sleep = (msec) => new Promise((resolve) => setTimeout(resolve, msec));
418
+ let failed = false;
419
+ let ready = false;
420
+ while (!ready) {
421
+ yield sleep(failed ? retry : delay);
422
+ failed = false;
423
+ let lwResp2;
424
+ let lwData2;
425
+ try {
426
+ lwResp2 = yield fetch(sum, { credentials: "same-origin" });
427
+ lwData2 = yield lwResp2.json();
428
+ } catch (e) {
429
+ failed = true;
430
+ continue;
431
+ }
432
+ switch (lwData2.status) {
433
+ case void 0:
434
+ throw new LunkwillError(void 0, lwData2);
435
+ case "ready":
436
+ ready = true;
437
+ break;
438
+ case "cancelled":
439
+ throw new LunkwillRequestCancelled(lwData2);
440
+ case "failed":
441
+ throw new LunkwillRequestFailed(lwData2);
442
+ case "spooled":
443
+ case "processing":
444
+ case "buffering":
445
+ delay = lwData2.delay_ms;
446
+ break;
447
+ default:
448
+ throw new LunkwillError(void 0, lwData2);
191
449
  }
192
450
  }
193
- if (typeof resource === "string") {
194
- return this._fetchResourceBy({ keyname: resource }, opt);
195
- } else if (typeof resource === "number") {
196
- return this._fetchResourceById(resource, opt);
197
- } else if (isObject(resource)) {
198
- return this._fetchResourceBy(resource, opt);
451
+ return res;
452
+ });
453
+ }
454
+ function lunkwillFetch(lwRespUrl) {
455
+ return __async$3(this, null, function* () {
456
+ try {
457
+ return yield window.fetch(lwRespUrl, { credentials: "same-origin" });
458
+ } catch (e) {
459
+ throw new NetworksResponseError();
199
460
  }
200
- return Promise.resolve(void 0);
201
- }
202
- getOneOrFail(resource, requestOptions) {
203
- return this.getOne(resource, requestOptions).then((res) => {
204
- if (res) {
205
- return res;
461
+ });
462
+ }
463
+ const mediaContentTypes = [
464
+ "application/pdf",
465
+ "image/png",
466
+ "image/jpeg",
467
+ "image/tiff",
468
+ "text/csv"
469
+ ];
470
+ const mediaContentTypesRegex = new RegExp(mediaContentTypes.join("|"));
471
+ function isMediaContentType(contentType) {
472
+ return mediaContentTypesRegex.test(contentType);
473
+ }
474
+ function encodeQueryParams(value) {
475
+ const result = [];
476
+ for (const [k, v] of Object.entries(value)) {
477
+ if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
478
+ result.push(`${k}=${encodeURIComponent(v)}`);
479
+ } else if (Array.isArray(v)) {
480
+ result.push(`${k}=${v.map(encodeURIComponent).join(",")}`);
481
+ } else {
482
+ for (const [sk, sv] of Object.entries(v)) {
483
+ const ske = `${k}[${encodeURIComponent(sk)}]`;
484
+ if (typeof sv === "string" || typeof sv === "number" || typeof sv === "boolean") {
485
+ result.push(`${ske}=${encodeURIComponent(sv)}`);
486
+ } else if (Array.isArray(sv)) {
487
+ const sve = sv.map(encodeURIComponent);
488
+ result.push(`${ske}=${sve.join(",")}`);
489
+ }
206
490
  }
207
- throw new ResourceNotFoundError();
208
- });
491
+ }
209
492
  }
210
- /**
211
- * A fast way to retrieve resource ID for any resource definition.
212
- * @param resource - Any available resource definition
213
- *
214
- * @remarks
215
- * There are situations when exactly the resource id is needed
216
- * (for example, to compose the correct request to the api)
217
- * then this method will come in handy to facilitate the extraction of the identifier
218
- * if the resource is specified through a keyname or other parameters.
219
- */
220
- getId(resource, requestOptions) {
221
- if (typeof resource === "number") {
222
- return Promise.resolve(resource);
223
- } else if (typeof resource === "string" || isObject(resource)) {
224
- return this.getOne(resource, requestOptions).then((res) => {
225
- if (res) {
226
- return res.resource.id;
227
- }
228
- });
229
- }
230
- return Promise.resolve(void 0);
231
- }
232
- /**
233
- * A fast way to retrieve resource ID for any resource definition.
234
- * @param resource - Any available resource definition
235
- *
236
- * @remarks
237
- * Similar with {@link NgwConnector.getResourceId | getResourceId} but rise error if resource is not exist.
238
- * To not make one more checks if the resource is definitely exists
239
- */
240
- getIdOrFail(resource, requestOptions) {
241
- return this.getId(resource, requestOptions).then((resp) => {
242
- if (resp === void 0) {
243
- throw new Error();
244
- }
245
- return resp;
246
- });
493
+ return result.join("&");
494
+ }
495
+ function generateUrl(path, query) {
496
+ let urlParams = "";
497
+ if (query !== void 0) {
498
+ urlParams = "?" + encodeQueryParams(query);
247
499
  }
248
- getMany(resource, requestOptions) {
249
- return this._resourceCacheFilter(resource).then((items) => {
250
- if (!items.length) {
251
- const query = {};
252
- if (resource.keyname) {
253
- query.keyname = resource.keyname;
254
- } else {
255
- Object.assign(query, resourceToQuery(resource));
500
+ return path + urlParams;
501
+ }
502
+ function request(path, options, cacheEngine) {
503
+ return __async$3(this, null, function* () {
504
+ var _b, _c;
505
+ const defaults = {
506
+ method: "GET",
507
+ credentials: "same-origin",
508
+ headers: {}
509
+ };
510
+ const _a = __spreadValues$3(__spreadValues$3({}, defaults), options), {
511
+ withCredentials,
512
+ responseType,
513
+ cacheProps,
514
+ cacheName,
515
+ lunkwill,
516
+ cache,
517
+ query,
518
+ json
519
+ } = _a, opt = __objRest$2(_a, [
520
+ "withCredentials",
521
+ "responseType",
522
+ "cacheProps",
523
+ "cacheName",
524
+ "lunkwill",
525
+ "cache",
526
+ "query",
527
+ "json"
528
+ ]);
529
+ opt.method = (_b = opt.method) == null ? void 0 : _b.toUpperCase();
530
+ if (withCredentials) {
531
+ opt.credentials = "include";
532
+ }
533
+ let useLunkwill = false;
534
+ if (lunkwill !== void 0) {
535
+ lunkwill.toHeaders(opt.headers || {});
536
+ useLunkwill = true;
537
+ }
538
+ const lunkwillReturnUrl = !!opt.lunkwillReturnUrl;
539
+ delete opt.lunkwillReturnUrl;
540
+ if (json !== void 0) {
541
+ opt.body = JSON.stringify(json);
542
+ const headers = opt.headers || {};
543
+ headers["Content-Type"] = "application/json";
544
+ opt.headers = headers;
545
+ }
546
+ const url = generateUrl(path, query);
547
+ const makeRequest = () => __async$3(this, null, function* () {
548
+ let response;
549
+ try {
550
+ response = yield fetch(url, opt);
551
+ } catch (e) {
552
+ if (opt.signal && opt.signal.aborted) {
553
+ throw e;
256
554
  }
257
- return this.connector.get("resource.search", requestOptions, __spreadValues$2({
258
- serialization: "full"
259
- }, query)).then((resources) => {
260
- if ((requestOptions == null ? void 0 : requestOptions.cache) && resources) {
261
- for (const x of resources) {
262
- this.cache.add("resource.item", Promise.resolve(x), {
263
- id: x.resource.id
264
- });
265
- }
266
- }
267
- return resources;
268
- });
269
- }
270
- return items;
271
- });
272
- }
273
- getParent(resource, requestOptions) {
274
- return this.getOne(resource, requestOptions).then((child) => {
275
- if (child) {
276
- return this.getOne(child.resource.parent.id, requestOptions);
277
- }
278
- return Promise.resolve(void 0);
279
- });
280
- }
281
- getChildrenOf(resource, requestOptions) {
282
- return this.getIdOrFail(resource).then(
283
- (parent) => this._getChildrenOf(parent, requestOptions)
284
- );
285
- }
286
- update(resource, data) {
287
- return this.getId(resource).then((id) => {
288
- if (id !== void 0) {
289
- return this.connector.put("resource.item", { data }, { id });
290
- }
291
- });
292
- }
293
- /**
294
- * Fast way to delete resource from NGW and clean cache.
295
- * @param resource - Resource definition
296
- */
297
- delete(resource) {
298
- return this.getId(resource).then((id) => {
299
- if (id !== void 0) {
300
- return this.connector.delete("resource.item", null, { id }).then(() => {
301
- this._cleanResourceItemCache(id);
302
- return void 0;
303
- });
555
+ throw new NetworksResponseError();
304
556
  }
305
- });
306
- }
307
- _getChildrenOf(parent, requestOptions, _items = []) {
308
- return this.connector.get("resource.collection", requestOptions, {
309
- parent
310
- }).then((items) => {
311
- const recursivePromises = [];
312
- for (const item of items) {
313
- if (requestOptions == null ? void 0 : requestOptions.cache) {
314
- this.cache.add("resource.item", Promise.resolve(item), {
315
- id: item.resource.id
316
- });
317
- }
318
- _items.push(item);
319
- if ((requestOptions == null ? void 0 : requestOptions.recursive) && item.resource.children) {
320
- recursivePromises.push(
321
- this._getChildrenOf(item.resource.id, requestOptions, _items)
322
- );
557
+ if (useLunkwill && lunkwillCheckResponse(response)) {
558
+ const lwRespUrl = yield lunkwillResponseUrl(response);
559
+ if (lunkwillReturnUrl) {
560
+ return lwRespUrl;
323
561
  }
562
+ response = yield lunkwillFetch(lwRespUrl);
324
563
  }
325
- if (recursivePromises.length) {
326
- return Promise.all(recursivePromises).then(() => {
327
- return _items;
328
- });
329
- }
330
- return _items;
331
- });
332
- }
333
- _cleanResourceItemCache(id) {
334
- return __async$2(this, null, function* () {
335
- var _a;
336
- const all = this.cache.all();
337
- const toDelete = [];
338
- for (const c of all) {
339
- const cid = (_a = c.props) == null ? void 0 : _a.id;
340
- if (["resource.item", "resource"].includes(c.key) && cid !== void 0) {
341
- if (typeof cid === "number") {
342
- if (cid === id) {
343
- toDelete.push(c);
344
- }
345
- } else {
346
- const rid = yield this.getId(cid);
347
- if (rid === id) {
348
- toDelete.push(c);
349
- }
350
- }
564
+ const respCType = response.headers.get("content-type");
565
+ const respJSON = respCType && (respCType.includes("application/json") || respCType.includes("application/vnd.lunkwill.request-summary+json"));
566
+ let body;
567
+ try {
568
+ const respMedia = respCType && isMediaContentType(respCType);
569
+ if (responseType === "blob" || respMedia) {
570
+ body = yield response.blob();
571
+ } else if (respJSON) {
572
+ body = yield response.json();
573
+ } else {
574
+ throw new InvalidResponseError();
575
+ }
576
+ } catch (e) {
577
+ if (e.name === "AbortError" || e instanceof InvalidResponseError) {
578
+ throw e;
351
579
  }
580
+ throw new InvalidResponseError();
352
581
  }
353
- for (const d of toDelete) {
354
- this.cache.delete(d);
582
+ if (400 <= response.status && response.status <= 599) {
583
+ throw new ServerResponseError(body);
355
584
  }
585
+ return body;
356
586
  });
357
- }
358
- _fetchResourceById(id, requestOptions) {
359
- return this.connector.get("resource.item", requestOptions, { id });
360
- }
361
- _fetchResourceBy(resource, requestOptions) {
362
- return this.getMany(resource, requestOptions).then((resources) => {
363
- return resources[0];
364
- });
365
- }
366
- _resourceCacheFilter(resource) {
367
- return Promise.all(this.cache.matchAll("resource.item")).then(
368
- (resources) => {
369
- const items = [];
370
- resources.filter((x) => {
371
- if (x) {
372
- if (resource.keyname && x.resource.keyname) {
373
- return resource.keyname === x.resource.keyname;
374
- }
375
- if (defined(resource.id) && defined(x.resource.id)) {
376
- return resource.id === x.resource.id;
377
- }
378
- return resourceCompare(resource, x.resource);
379
- }
380
- });
381
- return items;
382
- }
383
- );
384
- }
385
- }
386
-
387
- const CONNECTORS = [];
388
- function addConnector(connector) {
389
- CONNECTORS.push(connector);
390
- }
391
- function findConnector(options) {
392
- return CONNECTORS.find((x) => {
393
- if (x.options.baseUrl === options.baseUrl) {
394
- if (options.auth) {
395
- if (x.options.auth) {
396
- return objectDeepEqual(x.options.auth, options.auth);
587
+ if (cacheEngine) {
588
+ if (((_c = opt.method) == null ? void 0 : _c.toUpperCase()) === "GET") {
589
+ if (cache !== false) {
590
+ const props = cacheProps ? cacheProps : __spreadValues$3({}, objectRemoveEmpty({
591
+ withCredentials,
592
+ responseType
593
+ }));
594
+ return cacheEngine.add(cacheName || url, makeRequest, {
595
+ props,
596
+ expirationTime: cache ? void 0 : 500
597
+ });
397
598
  }
398
599
  } else {
399
- return true;
600
+ const ignoredForClean = ["api/feature_layer/identify"];
601
+ if (ignoredForClean.every((part) => !path.includes(part))) {
602
+ cacheEngine.clean();
603
+ }
400
604
  }
401
605
  }
606
+ return makeRequest();
402
607
  });
403
608
  }
404
- function removeConnector(connector) {
405
- const index = CONNECTORS.indexOf(connector);
406
- if (index !== -1) {
407
- CONNECTORS.splice(index, 1);
408
- }
409
- }
410
-
411
- class AbortError extends Error {
412
- constructor(message = "AbortError") {
413
- super(message);
414
- this.name = "AbortError";
415
- }
416
- }
417
609
 
418
610
  var __defProp$3 = Object.defineProperty;
611
+ var __defProps$2 = Object.defineProperties;
612
+ var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
613
+ var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
614
+ var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
615
+ var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
419
616
  var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
420
- var __publicField$2 = (obj, key, value) => __defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
421
- class InsufficientPermissionsError extends NgwError {
422
- constructor(obj) {
423
- super(obj);
424
- __publicField$2(this, "name", "InsufficientPermissionsError");
425
- __publicField$2(this, "exception", "nextgisweb.core.exception.InsufficientPermissions");
426
- Object.setPrototypeOf(this, InsufficientPermissionsError.prototype);
427
- }
428
- }
429
-
430
- const templateRe = /\{ *([\w_-]+) *\}/g;
431
- function template(str, data) {
432
- return str.replace(templateRe, (s, key) => {
433
- let value = data[key];
434
- if (value === void 0) {
435
- throw new Error("No value provided for letiable " + s);
436
- } else if (typeof value === "function") {
437
- value = value(data);
438
- }
439
- return value;
440
- });
441
- }
442
-
443
- var __defProp$2 = Object.defineProperty;
444
- var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
445
- var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
446
- var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
447
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
448
- var __spreadValues$1 = (a, b) => {
617
+ var __spreadValues$2 = (a, b) => {
449
618
  for (var prop in b || (b = {}))
450
- if (__hasOwnProp$1.call(b, prop))
451
- __defNormalProp$2(a, prop, b[prop]);
452
- if (__getOwnPropSymbols$1)
453
- for (var prop of __getOwnPropSymbols$1(b)) {
454
- if (__propIsEnum$1.call(b, prop))
455
- __defNormalProp$2(a, prop, b[prop]);
619
+ if (__hasOwnProp$2.call(b, prop))
620
+ __defNormalProp$3(a, prop, b[prop]);
621
+ if (__getOwnPropSymbols$2)
622
+ for (var prop of __getOwnPropSymbols$2(b)) {
623
+ if (__propIsEnum$2.call(b, prop))
624
+ __defNormalProp$3(a, prop, b[prop]);
456
625
  }
457
626
  return a;
458
627
  };
459
- var __async$1 = (__this, __arguments, generator) => {
628
+ var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
629
+ var __objRest$1 = (source, exclude) => {
630
+ var target = {};
631
+ for (var prop in source)
632
+ if (__hasOwnProp$2.call(source, prop) && exclude.indexOf(prop) < 0)
633
+ target[prop] = source[prop];
634
+ if (source != null && __getOwnPropSymbols$2)
635
+ for (var prop of __getOwnPropSymbols$2(source)) {
636
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$2.call(source, prop))
637
+ target[prop] = source[prop];
638
+ }
639
+ return target;
640
+ };
641
+ var __async$2 = (__this, __arguments, generator) => {
460
642
  return new Promise((resolve, reject) => {
461
643
  var fulfilled = (value) => {
462
644
  try {
@@ -476,68 +658,84 @@ var __async$1 = (__this, __arguments, generator) => {
476
658
  step((generator = generator.apply(__this, __arguments)).next());
477
659
  });
478
660
  };
479
- function apiRequest(opt) {
480
- return __async$1(this, null, function* () {
481
- const { params, name, connector, requestOptions } = opt;
482
- const apiItems = yield connector.connect();
483
- let apiItem = apiItems && apiItems[name];
484
- if (apiItem) {
485
- apiItem = [...apiItem];
486
- let url = apiItem.shift();
487
- if (apiItem.length) {
488
- const replaceParams = {};
489
- for (let fry = 0; fry < apiItem.length; fry++) {
490
- const arg = apiItem[fry];
491
- replaceParams[fry] = `{${arg}}`;
492
- if (params[arg] === void 0) {
493
- throw new Error(`\`${arg}\` URL API argument is not specified`);
494
- }
495
- }
496
- if (url) {
497
- url = template(url, replaceParams);
498
- }
661
+ function routeURL(name, baseUrl, routeData, ...rest) {
662
+ const [template, ...params] = routeData[name];
663
+ const first = rest[0];
664
+ let sub;
665
+ if (first === void 0) {
666
+ sub = [];
667
+ } else if (typeof first === "object" && first !== null) {
668
+ if (rest.length > 1) {
669
+ throw new Error("Too many arguments for route(name, object)!");
670
+ }
671
+ sub = [];
672
+ for (const [p, v] of Object.entries(first)) {
673
+ sub[params.indexOf(p)] = String(v);
674
+ }
675
+ } else {
676
+ sub = rest.map((v) => String(v));
677
+ }
678
+ return fixUrlStr(
679
+ baseUrl + template.replace(/\{(\w+)\}/g, function(m, a) {
680
+ const idx = parseInt(a);
681
+ const value = sub[idx];
682
+ if (value === void 0) {
683
+ const msg = `Undefined parameter ${idx} in "${template}".`;
684
+ throw new Error(msg);
499
685
  }
500
- if (params) {
501
- const paramArray = [];
502
- const paramList = params.paramList;
503
- if (Array.isArray(paramList)) {
504
- paramList.forEach(([key, value]) => {
505
- paramArray.push(`${key}=${value}`);
506
- });
507
- }
508
- for (const p in params) {
509
- if (apiItem.indexOf(p) === -1) {
510
- paramArray.push(`${p}=${params[p]}`);
511
- }
512
- }
513
- if (paramArray.length) {
514
- url = `${url}?${paramArray.join("&")}`;
515
- }
516
- }
517
- if (url) {
518
- return connector.makeQuery(url, params, __spreadValues$1({
519
- cacheName: name
520
- }, requestOptions));
521
- } else {
522
- throw new Error("Request URL is not set");
686
+ return String(value);
687
+ })
688
+ );
689
+ }
690
+ function route(name, connector, ...rest) {
691
+ const result = {
692
+ url: (opt) => __async$2(this, null, function* () {
693
+ var _a;
694
+ const routeData = yield connector.connect();
695
+ const template = routeURL(
696
+ name,
697
+ (_a = connector.options.baseUrl) != null ? _a : "",
698
+ routeData,
699
+ ...rest
700
+ );
701
+ return generateUrl(template, opt == null ? void 0 : opt.query);
702
+ })
703
+ };
704
+ const methods = ["get", "post", "put", "delete", "patch"];
705
+ for (const method of methods) {
706
+ const methodResp = (requestOptions) => {
707
+ var _b;
708
+ const _a = requestOptions || {}, { headers: optHeaders } = _a, restOpt = __objRest$1(_a, ["headers"]);
709
+ if ((_b = requestOptions == null ? void 0 : requestOptions.signal) == null ? void 0 : _b.aborted) {
710
+ throw new AbortError();
523
711
  }
524
- } else {
525
- return void 0;
526
- }
527
- });
712
+ return connector.connect().then((routeData) => {
713
+ var _a2;
714
+ const template = routeURL(
715
+ name,
716
+ (_a2 = connector.options.baseUrl) != null ? _a2 : "",
717
+ routeData,
718
+ ...rest
719
+ );
720
+ const headers = objectRemoveEmpty(__spreadValues$2(__spreadValues$2({}, connector.getAuthorizationHeaders()), optHeaders != null ? optHeaders : {}));
721
+ return request(
722
+ template,
723
+ __spreadProps$2(__spreadValues$2({
724
+ headers
725
+ }, restOpt), {
726
+ method
727
+ }),
728
+ connector.cache
729
+ );
730
+ });
731
+ };
732
+ result[method] = methodResp;
733
+ }
734
+ return result;
528
735
  }
529
736
 
530
- var __defProp$1 = Object.defineProperty;
531
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
532
- var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, key + "" , value);
533
- class NetworkError extends Error {
534
- constructor(url) {
535
- super();
536
- __publicField$1(this, "name", "NetworkError");
537
- Object.setPrototypeOf(this, NetworkError.prototype);
538
- this.message = `Unable to request ${url}.
539
- Possibly invalid NGW URL entered or CORS not configured to get request from ${location.origin}`;
540
- }
737
+ function isObject(val) {
738
+ return Object.prototype.toString.call(val) === "[object Object]";
541
739
  }
542
740
 
543
741
  let loadData;
@@ -552,7 +750,7 @@ let loadData;
552
750
  const getResponseText = () => {
553
751
  try {
554
752
  return JSON.parse(xhr.responseText);
555
- } catch (er) {
753
+ } catch (e) {
556
754
  return xhr.responseText;
557
755
  }
558
756
  };
@@ -598,62 +796,449 @@ let loadData;
598
796
  }
599
797
  }
600
798
  }
601
- if (options.withCredentials !== void 0) {
602
- xhr.withCredentials = options.withCredentials;
603
- }
604
- let data;
605
- if (options.file) {
606
- data = new FormData();
607
- data.append("file", options.file);
608
- if (options.data) {
609
- for (const d in options.data) {
610
- data.append(d, data[d]);
799
+ if (options.withCredentials !== void 0) {
800
+ xhr.withCredentials = options.withCredentials;
801
+ }
802
+ let data;
803
+ if (options.file) {
804
+ data = new FormData();
805
+ data.append("file", options.file);
806
+ if (options.data) {
807
+ for (const d in options.data) {
808
+ data.append(d, data[d]);
809
+ }
810
+ }
811
+ } else {
812
+ data = options.data ? typeof options.data === "string" ? options.data : JSON.stringify(options.data) : null;
813
+ }
814
+ if (onCancel) {
815
+ onCancel(() => {
816
+ xhr.abort();
817
+ });
818
+ }
819
+ xhr.send(data);
820
+ };
821
+ }
822
+
823
+ const CONNECTORS = [];
824
+ function addConnector(connector) {
825
+ CONNECTORS.push(connector);
826
+ }
827
+ function findConnector(options) {
828
+ return CONNECTORS.find((x) => {
829
+ if (x.options.baseUrl === options.baseUrl) {
830
+ if (options.auth) {
831
+ if (x.options.auth) {
832
+ return objectDeepEqual(x.options.auth, options.auth);
833
+ }
834
+ } else {
835
+ return true;
836
+ }
837
+ }
838
+ });
839
+ }
840
+ function removeConnector(connector) {
841
+ const index = CONNECTORS.indexOf(connector);
842
+ if (index !== -1) {
843
+ CONNECTORS.splice(index, 1);
844
+ }
845
+ }
846
+
847
+ var __defProp$2 = Object.defineProperty;
848
+ var __defProps$1 = Object.defineProperties;
849
+ var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
850
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
851
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
852
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
853
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
854
+ var __spreadValues$1 = (a, b) => {
855
+ for (var prop in b || (b = {}))
856
+ if (__hasOwnProp$1.call(b, prop))
857
+ __defNormalProp$2(a, prop, b[prop]);
858
+ if (__getOwnPropSymbols$1)
859
+ for (var prop of __getOwnPropSymbols$1(b)) {
860
+ if (__propIsEnum$1.call(b, prop))
861
+ __defNormalProp$2(a, prop, b[prop]);
862
+ }
863
+ return a;
864
+ };
865
+ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
866
+ var __objRest = (source, exclude) => {
867
+ var target = {};
868
+ for (var prop in source)
869
+ if (__hasOwnProp$1.call(source, prop) && exclude.indexOf(prop) < 0)
870
+ target[prop] = source[prop];
871
+ if (source != null && __getOwnPropSymbols$1)
872
+ for (var prop of __getOwnPropSymbols$1(source)) {
873
+ if (exclude.indexOf(prop) < 0 && __propIsEnum$1.call(source, prop))
874
+ target[prop] = source[prop];
875
+ }
876
+ return target;
877
+ };
878
+ var __publicField$2 = (obj, key, value) => __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
879
+ var __async$1 = (__this, __arguments, generator) => {
880
+ return new Promise((resolve, reject) => {
881
+ var fulfilled = (value) => {
882
+ try {
883
+ step(generator.next(value));
884
+ } catch (e) {
885
+ reject(e);
886
+ }
887
+ };
888
+ var rejected = (value) => {
889
+ try {
890
+ step(generator.throw(value));
891
+ } catch (e) {
892
+ reject(e);
893
+ }
894
+ };
895
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
896
+ step((generator = generator.apply(__this, __arguments)).next());
897
+ });
898
+ };
899
+ let ID = 0;
900
+ let REQUEST_ID = 0;
901
+ class NgwConnector {
902
+ constructor(options) {
903
+ this.options = options;
904
+ __publicField$2(this, "id", ID++);
905
+ __publicField$2(this, "emitter", new EventEmitter());
906
+ __publicField$2(this, "user");
907
+ __publicField$2(this, "cache");
908
+ __publicField$2(this, "withCredentials");
909
+ // Dedicated cache for route requests, as these are executed before any other requests.
910
+ // This cache does not need to be cleared during the session.
911
+ __publicField$2(this, "routeCache");
912
+ __publicField$2(this, "client", `NextGIS-NGW-Connector/${pkg.version}`);
913
+ __publicField$2(this, "routeStr", "/api/component/pyramid/route");
914
+ __publicField$2(this, "activeRequests", {});
915
+ __publicField$2(this, "requestTransform");
916
+ const exist = findConnector(options);
917
+ this.cache = new Cache({ namespace: options.cacheId });
918
+ this.routeCache = new Cache({ namespace: "routecache" });
919
+ if (exist) {
920
+ return exist;
921
+ } else {
922
+ const { route: route2, requestTransform, withCredentials } = this.options;
923
+ if (route2) {
924
+ this.routeStr = route2;
925
+ }
926
+ if (requestTransform) {
927
+ this.requestTransform = requestTransform;
928
+ }
929
+ if (withCredentials !== void 0) {
930
+ this.withCredentials = withCredentials;
931
+ }
932
+ addConnector(this);
933
+ }
934
+ }
935
+ /**
936
+ * Clear the cache.
937
+ */
938
+ clearCache() {
939
+ this.cache.clean();
940
+ }
941
+ setRequestTransform(requestTransform) {
942
+ this.requestTransform = requestTransform;
943
+ }
944
+ /**
945
+ * Fast way to specify the connection address to NextGIS Web.
946
+ * The current connection will be severed.
947
+ * @param baseUrl - NGW url
948
+ */
949
+ setNgw(baseUrl) {
950
+ this.logout();
951
+ this.options.baseUrl = baseUrl;
952
+ addConnector(this);
953
+ }
954
+ /**
955
+ * Establishing a connection with NextGIS Web to fulfill all other requests.
956
+ * @remarks
957
+ * This method need not be called manually as it is used when forming a request in {@link apiRequest | apiRequest}.
958
+ * Can be used to check connection.
959
+ * @example
960
+ * ```javascript
961
+ * const connector = new NgwConnector({ baseUrl: 'https://demo.nextgis.com' });
962
+ * connector.connect()
963
+ * .then(() => console.log('Ok'))
964
+ * .catch((er) => console.log('Connection problem', er));
965
+ * ```
966
+ */
967
+ connect() {
968
+ return __async$1(this, arguments, function* ({
969
+ signal
970
+ } = {}) {
971
+ const auth = this.options.auth;
972
+ if (auth) {
973
+ const { login, password } = auth;
974
+ if (login && password) {
975
+ yield this._login({ login, password });
976
+ }
977
+ }
978
+ const routeUrl = `${this.routeStr}?client=${this.client}`;
979
+ return this.routeCache.add(
980
+ this.options.baseUrl || String(this.id),
981
+ () => this.makeQuery(routeUrl, null, { signal, cache: false })
982
+ );
983
+ });
984
+ }
985
+ /**
986
+ * Quick way to change NextGIS Web user.
987
+ * @param credentials - New user credentials
988
+ */
989
+ login(credentials, options) {
990
+ this.logout();
991
+ addConnector(this);
992
+ return this._login(credentials, options);
993
+ }
994
+ /**
995
+ * Disconnecting a user. Aborting all current requests
996
+ */
997
+ logout() {
998
+ this.abort();
999
+ removeConnector(this);
1000
+ this.options.auth = void 0;
1001
+ this.user = void 0;
1002
+ this.routeCache.clean();
1003
+ this.clearCache();
1004
+ this.emitter.emit("logout");
1005
+ }
1006
+ getUserInfo(credentials, options) {
1007
+ return __async$1(this, null, function* () {
1008
+ if (this.user && this.user.id) {
1009
+ return this.user;
1010
+ }
1011
+ if (credentials) {
1012
+ this.options.auth = credentials;
1013
+ }
1014
+ const options_ = __spreadValues$1({
1015
+ headers: this.getAuthorizationHeaders(credentials),
1016
+ cache: true
1017
+ }, options);
1018
+ return this.makeQuery(
1019
+ "/api/component/auth/current_user",
1020
+ {},
1021
+ options_
1022
+ );
1023
+ });
1024
+ }
1025
+ /**
1026
+ * Obtaining the required Headers for authentication of requests in the NGW.
1027
+ */
1028
+ getAuthorizationHeaders(credentials) {
1029
+ const client = this.makeClientId(credentials);
1030
+ if (client) {
1031
+ return {
1032
+ Authorization: `Basic ${client}`
1033
+ };
1034
+ }
1035
+ return {};
1036
+ }
1037
+ makeClientId(credentials) {
1038
+ credentials = credentials || this.options.auth;
1039
+ if (credentials) {
1040
+ const { login, password } = credentials;
1041
+ const encodedStr = [login, password].map(encodeURIComponent).join(":");
1042
+ {
1043
+ return window.btoa(encodedStr);
1044
+ }
1045
+ }
1046
+ }
1047
+ /** Stop all api requests */
1048
+ abort() {
1049
+ for (const abortController of Object.values(this.activeRequests)) {
1050
+ abortController.abort();
1051
+ }
1052
+ this.activeRequests = {};
1053
+ }
1054
+ getActiveApiRequests() {
1055
+ return __spreadValues$1({}, this.activeRequests);
1056
+ }
1057
+ route(name, ...rest) {
1058
+ return route(name, this, ...rest);
1059
+ }
1060
+ /**
1061
+ * Send request to NGW.
1062
+ * @param url - URL address to NGW
1063
+ * @param params - Query params
1064
+ * @param options - Request options
1065
+ */
1066
+ makeQuery(_0, _1) {
1067
+ return __async$1(this, arguments, function* (url, params, options = {}) {
1068
+ var _b;
1069
+ url = (this.options.baseUrl ? this.options.baseUrl : "") + url;
1070
+ if (!url) {
1071
+ throw new Error("Empty `url` not allowed");
1072
+ }
1073
+ if (params) {
1074
+ const _a = params, restParams = __objRest(_a, ["paramList"]);
1075
+ url = template(url, restParams);
1076
+ }
1077
+ url = encodeURI(fixUrlStr(url));
1078
+ options = __spreadValues$1({ withCredentials: this.withCredentials }, options);
1079
+ const {
1080
+ cache,
1081
+ signal: externalSignal,
1082
+ method = "GET",
1083
+ headers,
1084
+ cacheName,
1085
+ cacheProps,
1086
+ responseType,
1087
+ withCredentials
1088
+ } = options;
1089
+ const internalAbortController = new AbortController();
1090
+ const internalSignal = internalAbortController.signal;
1091
+ if (externalSignal) {
1092
+ if (externalSignal.aborted) {
1093
+ throw new AbortError();
1094
+ }
1095
+ externalSignal.addEventListener("abort", () => {
1096
+ internalAbortController.abort();
1097
+ });
1098
+ }
1099
+ options.signal = internalSignal;
1100
+ const createPromise = () => __async$1(this, null, function* () {
1101
+ const id = REQUEST_ID++;
1102
+ this.activeRequests[id] = internalAbortController;
1103
+ try {
1104
+ return this._loadData(url, options);
1105
+ } finally {
1106
+ this._cleanActiveRequest(id);
1107
+ }
1108
+ });
1109
+ if (method === "GET" && cache !== false) {
1110
+ const cacheOptions = cacheProps ? cacheProps : __spreadProps$1(__spreadValues$1({}, objectRemoveEmpty({
1111
+ headers,
1112
+ withCredentials,
1113
+ responseType,
1114
+ baseUrl: this.options.baseUrl,
1115
+ userId: (_b = this.user) == null ? void 0 : _b.id
1116
+ })), {
1117
+ params
1118
+ });
1119
+ return this.cache.add(cacheName || url, createPromise, {
1120
+ props: cacheOptions,
1121
+ expirationTime: cache ? void 0 : 500
1122
+ });
1123
+ }
1124
+ return createPromise();
1125
+ });
1126
+ }
1127
+ _loadData(url, options) {
1128
+ options.responseType = options.responseType || "json";
1129
+ return new Promise((resolve, reject) => {
1130
+ var _a;
1131
+ if (this.user) {
1132
+ options = options || {};
1133
+ options.headers = __spreadValues$1(__spreadValues$1({}, this.getAuthorizationHeaders()), options.headers);
1134
+ }
1135
+ if (this.requestTransform) {
1136
+ const [transUrl, transOptions] = this.requestTransform(url, options);
1137
+ url = transUrl;
1138
+ options = transOptions;
1139
+ }
1140
+ let runOnAbort = void 0;
1141
+ loadData(url, resolve, options, reject, (handler) => {
1142
+ runOnAbort = handler;
1143
+ });
1144
+ (_a = options.signal) == null ? void 0 : _a.addEventListener("abort", () => {
1145
+ if (runOnAbort !== void 0) {
1146
+ runOnAbort();
1147
+ }
1148
+ reject(new AbortError());
1149
+ });
1150
+ }).catch((httpError) => {
1151
+ if (httpError.name !== "AbortError") {
1152
+ if (!!(process.env.NODE_ENV !== "production")) {
1153
+ console.warn("DEV WARN", httpError);
1154
+ }
1155
+ const er = this._handleHttpError(httpError);
1156
+ if (er) {
1157
+ throw er;
1158
+ }
1159
+ }
1160
+ throw httpError;
1161
+ });
1162
+ }
1163
+ _login(credentials, options) {
1164
+ return __async$1(this, null, function* () {
1165
+ try {
1166
+ const data = yield this.getUserInfo(credentials, options);
1167
+ this.user = data;
1168
+ this.emitter.emit("login", data);
1169
+ return data;
1170
+ } catch (er) {
1171
+ this.emitter.emit("login:error", er);
1172
+ throw er;
1173
+ }
1174
+ });
1175
+ }
1176
+ _cleanActiveRequest(requestId) {
1177
+ delete this.activeRequests[requestId];
1178
+ }
1179
+ _handleHttpError(er) {
1180
+ if (er) {
1181
+ if (er instanceof NgwError) {
1182
+ if (er.exception === "nextgisweb.resource.exception.ResourceNotFound") {
1183
+ throw new ResourceNotFoundError(er);
1184
+ } else if (er.exception === "nextgisweb.core.exception.InsufficientPermissions") {
1185
+ throw new InsufficientPermissionsError(er);
1186
+ }
1187
+ }
1188
+ }
1189
+ return er;
1190
+ }
1191
+ }
1192
+ __publicField$2(NgwConnector, "errors", errors);
1193
+
1194
+ function resourceCompare(res1, res2) {
1195
+ return objectDeepEqual(res1, res2);
1196
+ }
1197
+
1198
+ const exclude = ["description"];
1199
+ function resourceToQuery(resource, prefix = "") {
1200
+ prefix = prefix ? prefix + "__" : "";
1201
+ const query = {};
1202
+ for (const [key, value] of Object.entries(resource)) {
1203
+ if (exclude.indexOf(key) === -1) {
1204
+ if (isObject(value)) {
1205
+ if (key === "owner_user") {
1206
+ const children = resourceToQuery(
1207
+ value,
1208
+ key
1209
+ );
1210
+ Object.assign(query, children);
1211
+ } else if (key === "parent" && "id" in value) {
1212
+ query.parent_id = value.id;
611
1213
  }
1214
+ } else if (defined(value)) {
1215
+ query[prefix + key] = value;
612
1216
  }
613
- } else {
614
- data = options.data ? typeof options.data === "string" ? options.data : JSON.stringify(options.data) : null;
615
- }
616
- if (onCancel) {
617
- onCancel(() => {
618
- xhr.abort();
619
- });
620
1217
  }
621
- xhr.send(data);
622
- };
1218
+ }
1219
+ return query;
623
1220
  }
624
1221
 
625
- var __defProp = Object.defineProperty;
1222
+ var __defProp$1 = Object.defineProperty;
626
1223
  var __defProps = Object.defineProperties;
627
1224
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
628
1225
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
629
1226
  var __hasOwnProp = Object.prototype.hasOwnProperty;
630
1227
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
631
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1228
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
632
1229
  var __spreadValues = (a, b) => {
633
1230
  for (var prop in b || (b = {}))
634
1231
  if (__hasOwnProp.call(b, prop))
635
- __defNormalProp(a, prop, b[prop]);
1232
+ __defNormalProp$1(a, prop, b[prop]);
636
1233
  if (__getOwnPropSymbols)
637
1234
  for (var prop of __getOwnPropSymbols(b)) {
638
1235
  if (__propIsEnum.call(b, prop))
639
- __defNormalProp(a, prop, b[prop]);
1236
+ __defNormalProp$1(a, prop, b[prop]);
640
1237
  }
641
1238
  return a;
642
1239
  };
643
1240
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
644
- var __objRest = (source, exclude) => {
645
- var target = {};
646
- for (var prop in source)
647
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
648
- target[prop] = source[prop];
649
- if (source != null && __getOwnPropSymbols)
650
- for (var prop of __getOwnPropSymbols(source)) {
651
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
652
- target[prop] = source[prop];
653
- }
654
- return target;
655
- };
656
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1241
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
657
1242
  var __async = (__this, __arguments, generator) => {
658
1243
  return new Promise((resolve, reject) => {
659
1244
  var fulfilled = (value) => {
@@ -674,173 +1259,269 @@ var __async = (__this, __arguments, generator) => {
674
1259
  step((generator = generator.apply(__this, __arguments)).next());
675
1260
  });
676
1261
  };
677
- let ID = 0;
678
- let REQUEST_ID = 0;
679
- class NgwConnector {
680
- constructor(options) {
681
- this.options = options;
682
- __publicField(this, "id", ID++);
683
- __publicField(this, "emitter", new EventEmitter());
684
- __publicField(this, "user");
685
- __publicField(this, "resources");
686
- __publicField(this, "cache");
687
- __publicField(this, "withCredentials");
688
- __publicField(this, "client", `NextGIS-NGW-Connector/${pkg.version}`);
689
- __publicField(this, "routeStr", "/api/component/pyramid/route");
690
- __publicField(this, "activeRequests", {});
691
- __publicField(this, "requestTransform");
692
- const exist = findConnector(options);
693
- this.cache = new Cache({ namespace: options.cacheId });
694
- if (exist) {
695
- return exist;
696
- } else {
697
- const { route, requestTransform, withCredentials } = this.options;
698
- if (route) {
699
- this.routeStr = route;
700
- }
701
- if (requestTransform) {
702
- this.requestTransform = requestTransform;
703
- }
704
- if (withCredentials !== void 0) {
705
- this.withCredentials = withCredentials;
1262
+ class ResourcesControl {
1263
+ constructor({
1264
+ connector,
1265
+ cacheId
1266
+ }) {
1267
+ __publicField$1(this, "cache");
1268
+ __publicField$1(this, "connector");
1269
+ this.connector = connector;
1270
+ this.cache = new Cache({ namespace: cacheId });
1271
+ }
1272
+ // -------------------------------------------------------------------------
1273
+ // Resource Methods
1274
+ // -------------------------------------------------------------------------
1275
+ /**
1276
+ * Receive resource from NGW by id, keyname or search-object parameter.
1277
+ * @param resource - Resource id, keyname or search-object
1278
+ *
1279
+ * @remarks
1280
+ * Fetching resource would be cached to speed up next call
1281
+ */
1282
+ getOne(resource, requestOptions) {
1283
+ const opt = __spreadValues({}, requestOptions);
1284
+ if (typeof resource === "string") ; else if (typeof resource === "number") ; else if (isObject(resource)) {
1285
+ if (resource.id !== void 0) {
1286
+ resource.id;
1287
+ } else {
1288
+ if (resource.keyname) {
1289
+ resource.keyname;
1290
+ }
1291
+ if (resource.display_name) {
1292
+ resource.display_name;
1293
+ }
706
1294
  }
707
- this.resources = new ResourcesControl({
708
- connector: this,
709
- cacheId: options.cacheId
710
- });
711
- addConnector(this);
712
1295
  }
1296
+ if (typeof resource === "string") {
1297
+ return this._fetchResourceBy({ keyname: resource }, opt);
1298
+ } else if (typeof resource === "number") {
1299
+ return this._fetchResourceById(resource, opt);
1300
+ } else if (isObject(resource)) {
1301
+ return this._fetchResourceBy(resource, opt);
1302
+ }
1303
+ return Promise.resolve(void 0);
713
1304
  }
714
- static create(options) {
715
- return new this(options);
1305
+ getOneOrFail(resource, requestOptions) {
1306
+ return this.getOne(resource, requestOptions).then((res) => {
1307
+ if (res) {
1308
+ return res;
1309
+ }
1310
+ throw new ResourceNotFoundError();
1311
+ });
716
1312
  }
717
1313
  /**
718
- * Clear the cache.
1314
+ * A fast way to retrieve resource ID for any resource definition.
1315
+ * @param resource - Any available resource definition
1316
+ *
1317
+ * @remarks
1318
+ * There are situations when exactly the resource id is needed
1319
+ * (for example, to compose the correct request to the api)
1320
+ * then this method will come in handy to facilitate the extraction of the identifier
1321
+ * if the resource is specified through a keyname or other parameters.
719
1322
  */
720
- clearCache() {
721
- this.cache.clean();
722
- this.resources.cache.clean();
723
- }
724
- setRequestTransform(requestTransform) {
725
- this.requestTransform = requestTransform;
1323
+ getId(resource, requestOptions) {
1324
+ if (typeof resource === "number") {
1325
+ return Promise.resolve(resource);
1326
+ } else if (typeof resource === "string" || isObject(resource)) {
1327
+ return this.getOne(resource, requestOptions).then((res) => {
1328
+ if (res) {
1329
+ return res.resource.id;
1330
+ }
1331
+ });
1332
+ }
1333
+ return Promise.resolve(void 0);
726
1334
  }
727
1335
  /**
728
- * Fast way to specify the connection address to NextGIS Web.
729
- * The current connection will be severed.
730
- * @param baseUrl - NGW url
1336
+ * A fast way to retrieve resource ID for any resource definition.
1337
+ * @param resource - Any available resource definition
1338
+ *
1339
+ * @remarks
1340
+ * Similar with {@link NgwConnector.getResourceId | getResourceId} but rise error if resource is not exist.
1341
+ * To not make one more checks if the resource is definitely exists
731
1342
  */
732
- setNgw(baseUrl) {
733
- this.logout();
734
- this.options.baseUrl = baseUrl;
735
- addConnector(this);
1343
+ getIdOrFail(resource, requestOptions) {
1344
+ return this.getId(resource, requestOptions).then((resp) => {
1345
+ if (resp === void 0) {
1346
+ throw new Error();
1347
+ }
1348
+ return resp;
1349
+ });
1350
+ }
1351
+ getMany(resource, requestOptions) {
1352
+ return this._resourceCacheFilter(resource).then((items) => {
1353
+ if (!items.length) {
1354
+ const query = {};
1355
+ if (resource.keyname) {
1356
+ query.keyname = resource.keyname;
1357
+ } else {
1358
+ Object.assign(query, resourceToQuery(resource));
1359
+ }
1360
+ return this.connector.route("resource.search").get(__spreadProps(__spreadValues({}, requestOptions), {
1361
+ query: __spreadValues({
1362
+ serialization: "full"
1363
+ }, query)
1364
+ })).then((resources) => {
1365
+ if ((requestOptions == null ? void 0 : requestOptions.cache) && resources) {
1366
+ for (const x of resources) {
1367
+ this.cache.add("resource.item", Promise.resolve(x), {
1368
+ id: x.resource.id
1369
+ });
1370
+ }
1371
+ }
1372
+ return resources;
1373
+ });
1374
+ }
1375
+ return items;
1376
+ });
1377
+ }
1378
+ getParent(resource, requestOptions) {
1379
+ return this.getOne(resource, requestOptions).then((child) => {
1380
+ var _a, _b;
1381
+ if ((_b = (_a = child == null ? void 0 : child.resource) == null ? void 0 : _a.parent) == null ? void 0 : _b.id) {
1382
+ return this.getOne(child.resource.parent.id, requestOptions);
1383
+ }
1384
+ return Promise.resolve(void 0);
1385
+ });
1386
+ }
1387
+ getChildrenOf(resource, requestOptions) {
1388
+ return this.getIdOrFail(resource).then(
1389
+ (parent) => this._getChildrenOf(parent, requestOptions)
1390
+ );
1391
+ }
1392
+ update(resource, data) {
1393
+ return this.getId(resource).then((id) => {
1394
+ if (id !== void 0) {
1395
+ return this.connector.put("resource.item", { data }, { id });
1396
+ }
1397
+ });
736
1398
  }
737
1399
  /**
738
- * Establishing a connection with NextGIS Web to fulfill all other requests.
739
- * @remarks
740
- * This method need not be called manually as it is used when forming a request in {@link apiRequest | apiRequest}.
741
- * Can be used to check connection.
742
- * @example
743
- * ```javascript
744
- * const connector = new NgwConnector({baseUrl: 'https://demo.nextgis.com'});
745
- * connector.connect()
746
- * .then(() => console.log('Ok'))
747
- * .catch((er) => console.log('Connection problem', er));
748
- * ```
1400
+ * Fast way to delete resource from NGW and clean cache.
1401
+ * @param resource - Resource definition
749
1402
  */
750
- connect() {
751
- return __async(this, null, function* () {
752
- const auth = this.options.auth;
753
- if (auth) {
754
- const { login, password } = auth;
755
- if (login && password) {
756
- yield this._login({ login, password });
1403
+ delete(resource) {
1404
+ return this.getId(resource).then((id) => {
1405
+ if (id !== void 0) {
1406
+ return this.connector.delete("resource.item", null, { id }).then(() => {
1407
+ this._cleanResourceItemCache(id);
1408
+ return void 0;
1409
+ });
1410
+ }
1411
+ });
1412
+ }
1413
+ _getChildrenOf(_0, _1) {
1414
+ return __async(this, arguments, function* (parentDef, requestOptions, _items = []) {
1415
+ let parent = void 0;
1416
+ if (typeof parentDef === "string") {
1417
+ parent = yield this.getId(parentDef, requestOptions);
1418
+ } else if (typeof parentDef === "object") {
1419
+ parent = parentDef.id;
1420
+ } else {
1421
+ parent = parentDef;
1422
+ }
1423
+ const items = yield this.connector.route("resource.collection").get(__spreadProps(__spreadValues({}, requestOptions), {
1424
+ query: {
1425
+ parent
1426
+ }
1427
+ }));
1428
+ const recursivePromises = [];
1429
+ for (const item of items) {
1430
+ if (requestOptions == null ? void 0 : requestOptions.cache) {
1431
+ this.cache.add("resource.item", Promise.resolve(item), {
1432
+ id: item.resource.id
1433
+ });
757
1434
  }
758
- }
759
- const routeUrl = `${this.routeStr}?client=${this.client}`;
760
- return yield this.makeQuery(
761
- routeUrl,
762
- {},
763
- {
764
- cacheName: "route",
765
- cache: true,
766
- cacheProps: {
767
- id: this.id,
768
- auth,
769
- baseUrl: this.options.baseUrl
770
- }
1435
+ _items.push(item);
1436
+ if ((requestOptions == null ? void 0 : requestOptions.recursive) && item.resource.children) {
1437
+ recursivePromises.push(
1438
+ this._getChildrenOf(item.resource.id, requestOptions, _items)
1439
+ );
771
1440
  }
772
- );
1441
+ }
1442
+ if (recursivePromises.length) {
1443
+ return Promise.all(recursivePromises).then(() => {
1444
+ return _items;
1445
+ });
1446
+ }
1447
+ return _items;
773
1448
  });
774
1449
  }
775
- /**
776
- * Quick way to change NextGIS Web user.
777
- * @param credentials - New user credentials
778
- */
779
- login(credentials, options) {
780
- this.logout();
781
- addConnector(this);
782
- return this._login(credentials, options);
783
- }
784
- /**
785
- * Disconnecting a user. Aborting all current requests
786
- */
787
- logout() {
788
- this.abort();
789
- removeConnector(this);
790
- this.options.auth = void 0;
791
- this.user = void 0;
792
- this.clearCache();
793
- this.emitter.emit("logout");
794
- }
795
- getUserInfo(credentials, options) {
1450
+ _cleanResourceItemCache(id) {
796
1451
  return __async(this, null, function* () {
797
- if (this.user && this.user.id) {
798
- return this.user;
1452
+ var _a;
1453
+ const all = this.cache.all();
1454
+ const toDelete = [];
1455
+ for (const c of all) {
1456
+ const cid = (_a = c.props) == null ? void 0 : _a.id;
1457
+ if (["resource.item", "resource"].includes(c.key) && cid !== void 0) {
1458
+ if (typeof cid === "number") {
1459
+ if (cid === id) {
1460
+ toDelete.push(c);
1461
+ }
1462
+ } else {
1463
+ const rid = yield this.getId(cid);
1464
+ if (rid === id) {
1465
+ toDelete.push(c);
1466
+ }
1467
+ }
1468
+ }
799
1469
  }
800
- if (credentials) {
801
- this.options.auth = credentials;
1470
+ for (const d of toDelete) {
1471
+ this.cache.delete(d);
802
1472
  }
803
- const options_ = __spreadValues({
804
- headers: this.getAuthorizationHeaders(credentials)
805
- }, options);
806
- return this.makeQuery(
807
- "/api/component/auth/current_user",
808
- {},
809
- options_
810
- );
811
1473
  });
812
1474
  }
813
- /**
814
- * Obtaining the required Headers for authentication of requests in the NGW.
815
- */
816
- getAuthorizationHeaders(credentials) {
817
- const client = this.makeClientId(credentials);
818
- if (client) {
819
- return {
820
- Authorization: `Basic ${client}`
821
- };
822
- }
1475
+ _fetchResourceById(id, requestOptions) {
1476
+ return this.connector.route("resource.item", { id }).get(requestOptions);
823
1477
  }
824
- makeClientId(credentials) {
825
- credentials = credentials || this.options.auth;
826
- if (credentials) {
827
- const { login, password } = credentials;
828
- const str = `${login}:${password}`;
829
- const encodedStr = encodeURIComponent(str);
830
- {
831
- return window.btoa(encodedStr);
1478
+ _fetchResourceBy(resource, requestOptions) {
1479
+ return this.getMany(resource, requestOptions).then((resources) => {
1480
+ return resources[0];
1481
+ });
1482
+ }
1483
+ _resourceCacheFilter(resource) {
1484
+ return Promise.all(this.cache.matchAll("resource.item")).then(
1485
+ (resources) => {
1486
+ const items = [];
1487
+ resources.filter((x) => {
1488
+ if (x) {
1489
+ if (resource.keyname && x.resource.keyname) {
1490
+ return resource.keyname === x.resource.keyname;
1491
+ }
1492
+ if (defined(resource.id) && defined(x.resource.id)) {
1493
+ return resource.id === x.resource.id;
1494
+ }
1495
+ return resourceCompare(resource, x.resource);
1496
+ }
1497
+ });
1498
+ return items;
832
1499
  }
833
- }
1500
+ );
834
1501
  }
835
- /** Stop all api requests */
836
- abort() {
837
- for (const abortController of Object.values(this.activeRequests)) {
838
- abortController.abort();
839
- }
840
- this.activeRequests = {};
1502
+ }
1503
+
1504
+ var __defProp = Object.defineProperty;
1505
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1506
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1507
+ class NgwConnectorExtended extends NgwConnector {
1508
+ constructor(options) {
1509
+ super(options);
1510
+ __publicField(this, "resources");
1511
+ this.resources = new ResourcesControl({
1512
+ connector: this,
1513
+ cacheId: options.cacheId
1514
+ });
841
1515
  }
842
- getActiveApiRequests() {
843
- return __spreadValues({}, this.activeRequests);
1516
+ static create(options) {
1517
+ return new this(options);
1518
+ }
1519
+ /**
1520
+ * Clear the cache.
1521
+ */
1522
+ clearCache() {
1523
+ super.clearCache();
1524
+ this.resources.cache.clean();
844
1525
  }
845
1526
  /**
846
1527
  * Send request to NGW api router.
@@ -959,75 +1640,6 @@ class NgwConnector {
959
1640
  options
960
1641
  );
961
1642
  }
962
- /**
963
- * Send request to NGW.
964
- * @param url - URL address to NGW
965
- * @param params - Query params
966
- * @param options - Request options
967
- */
968
- makeQuery(_0, _1) {
969
- return __async(this, arguments, function* (url, params, options = {}) {
970
- var _b;
971
- url = (this.options.baseUrl ? this.options.baseUrl : "") + url;
972
- if (!url) {
973
- throw new Error("Empty `url` not allowed");
974
- }
975
- if (params) {
976
- const _a = params, restParams = __objRest(_a, ["paramList"]);
977
- url = template(url, restParams);
978
- }
979
- url = encodeURI(fixUrlStr(url));
980
- options = __spreadValues({ withCredentials: this.withCredentials }, options);
981
- const {
982
- cache,
983
- signal: externalSignal,
984
- method = "GET",
985
- headers,
986
- cacheName,
987
- cacheProps,
988
- responseType,
989
- withCredentials
990
- } = options;
991
- const internalAbortController = new AbortController();
992
- const internalSignal = internalAbortController.signal;
993
- if (externalSignal) {
994
- if (externalSignal.aborted) {
995
- throw new AbortError();
996
- }
997
- externalSignal.addEventListener("abort", () => {
998
- internalAbortController.abort();
999
- });
1000
- }
1001
- options.signal = internalSignal;
1002
- const createPromise = () => __async(this, null, function* () {
1003
- const id = REQUEST_ID++;
1004
- this.activeRequests[id] = internalAbortController;
1005
- try {
1006
- return this._loadData(url, options);
1007
- } finally {
1008
- this._cleanActiveRequest(id);
1009
- }
1010
- });
1011
- if (cache && method === "GET") {
1012
- const cacheOptions = cacheProps ? cacheProps : __spreadProps(__spreadValues({}, objectRemoveEmpty({
1013
- headers,
1014
- withCredentials,
1015
- responseType,
1016
- baseUrl: this.options.baseUrl,
1017
- userId: (_b = this.user) == null ? void 0 : _b.id
1018
- })), {
1019
- params
1020
- });
1021
- return this.cache.add(
1022
- cacheName || url,
1023
- createPromise,
1024
- cacheOptions,
1025
- false
1026
- );
1027
- }
1028
- return createPromise();
1029
- });
1030
- }
1031
1643
  // -------------------------------------------------------------------------
1032
1644
  // Resource Methods
1033
1645
  // -------------------------------------------------------------------------
@@ -1103,78 +1715,7 @@ class NgwConnector {
1103
1715
  deleteResource(resource) {
1104
1716
  return this.resources.delete(resource);
1105
1717
  }
1106
- /**
1107
- * @internal
1108
- */
1109
- _loadData(url, options) {
1110
- options.responseType = options.responseType || "json";
1111
- return new Promise((resolve, reject) => {
1112
- var _a;
1113
- if (this.user) {
1114
- options = options || {};
1115
- options.headers = __spreadValues(__spreadValues({}, this.getAuthorizationHeaders()), options.headers);
1116
- }
1117
- if (this.requestTransform) {
1118
- const [transUrl, transOptions] = this.requestTransform(url, options);
1119
- url = transUrl;
1120
- options = transOptions;
1121
- }
1122
- let runOnAbort = void 0;
1123
- loadData(url, resolve, options, reject, (handler) => {
1124
- runOnAbort = handler;
1125
- });
1126
- (_a = options.signal) == null ? void 0 : _a.addEventListener("abort", () => {
1127
- if (runOnAbort !== void 0) {
1128
- runOnAbort();
1129
- }
1130
- reject(new AbortError());
1131
- });
1132
- }).catch((httpError) => {
1133
- if (httpError.name !== "AbortError") {
1134
- if (!!(process.env.NODE_ENV !== "production")) {
1135
- console.warn("DEV WARN", httpError);
1136
- }
1137
- const er = this._handleHttpError(httpError);
1138
- if (er) {
1139
- throw er;
1140
- }
1141
- }
1142
- throw httpError;
1143
- });
1144
- }
1145
- _login(credentials, options) {
1146
- return __async(this, null, function* () {
1147
- try {
1148
- const data = yield this.getUserInfo(credentials, options);
1149
- this.user = data;
1150
- this.emitter.emit("login", data);
1151
- return data;
1152
- } catch (er) {
1153
- this.emitter.emit("login:error", er);
1154
- throw er;
1155
- }
1156
- });
1157
- }
1158
- _cleanActiveRequest(requestId) {
1159
- delete this.activeRequests[requestId];
1160
- }
1161
- _handleHttpError(er) {
1162
- if (er) {
1163
- if (er instanceof NgwError) {
1164
- if (er.exception === "nextgisweb.resource.exception.ResourceNotFound") {
1165
- throw new ResourceNotFoundError(er);
1166
- } else if (er.exception === "nextgisweb.core.exception.InsufficientPermissions") {
1167
- throw new InsufficientPermissionsError(er);
1168
- }
1169
- }
1170
- }
1171
- return er;
1172
- }
1173
1718
  }
1174
- __publicField(NgwConnector, "errors", {
1175
- NgwError,
1176
- ResourceNotFoundError
1177
- });
1178
1719
 
1179
- export { NgwConnector as default };
1720
+ export { NgwConnectorExtended as default };
1180
1721
  //# sourceMappingURL=ngw-connector.esm-bundler.js.map