@nextgis/ngw-connector 3.0.0-alpha.1 → 3.0.0-alpha.13

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