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

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,9 +1,8 @@
1
- /** Bundle of @nextgis/ngw-connector; version: 2.5.0; author: NextGIS */
1
+ /** Bundle of @nextgis/ngw-connector; version: 3.0.0-alpha.1; author: NextGIS */
2
2
  'use strict';
3
3
 
4
4
  var events = require('events');
5
5
  var Cache = require('@nextgis/cache');
6
- var CancelablePromise = require('@nextgis/cancelable-promise');
7
6
  var utils = require('@nextgis/utils');
8
7
 
9
8
  var __defProp$4 = Object.defineProperty;
@@ -90,39 +89,27 @@ class ResourcesControl {
90
89
  * Fetching resource would be cached to speed up next call
91
90
  */
92
91
  getOne(resource, requestOptions) {
93
- const cache = this.cache;
94
- const forCache = {};
95
- const opt = { ...requestOptions, cache: false };
96
- if (typeof resource === "string") {
97
- forCache.keyname = resource;
98
- } else if (typeof resource === "number") {
99
- forCache.id = resource;
100
- } else if (isObject(resource)) {
92
+ const opt = { ...requestOptions };
93
+ if (typeof resource === "string") ; else if (typeof resource === "number") ; else if (isObject(resource)) {
101
94
  if (resource.id !== void 0) {
102
- forCache.id = resource.id;
95
+ resource.id;
103
96
  } else {
104
97
  if (resource.keyname) {
105
- forCache.keyname = resource.keyname;
98
+ resource.keyname;
106
99
  }
107
100
  if (resource.display_name) {
108
- forCache.display_name = resource.display_name;
101
+ resource.display_name;
109
102
  }
110
103
  }
111
104
  }
112
- const makeRequest = () => {
113
- if (typeof resource === "string") {
114
- return this._fetchResourceBy({ keyname: resource }, opt);
115
- } else if (typeof resource === "number") {
116
- return this._fetchResourceById(resource, opt);
117
- } else if (isObject(resource)) {
118
- return this._fetchResourceBy(resource, opt);
119
- }
120
- return CancelablePromise.resolve(void 0);
121
- };
122
- if (requestOptions == null ? void 0 : requestOptions.cache) {
123
- return cache.addFull("resource", makeRequest, forCache);
105
+ if (typeof resource === "string") {
106
+ return this._fetchResourceBy({ keyname: resource }, opt);
107
+ } else if (typeof resource === "number") {
108
+ return this._fetchResourceById(resource, opt);
109
+ } else if (isObject(resource)) {
110
+ return this._fetchResourceBy(resource, opt);
124
111
  }
125
- return makeRequest();
112
+ return Promise.resolve(void 0);
126
113
  }
127
114
  getOneOrFail(resource, requestOptions) {
128
115
  return this.getOne(resource, requestOptions).then((res) => {
@@ -144,7 +131,7 @@ class ResourcesControl {
144
131
  */
145
132
  getId(resource, requestOptions) {
146
133
  if (typeof resource === "number") {
147
- return CancelablePromise.resolve(resource);
134
+ return Promise.resolve(resource);
148
135
  } else if (typeof resource === "string" || isObject(resource)) {
149
136
  return this.getOne(resource, requestOptions).then((res) => {
150
137
  if (res) {
@@ -152,7 +139,7 @@ class ResourcesControl {
152
139
  }
153
140
  });
154
141
  }
155
- return CancelablePromise.resolve(void 0);
142
+ return Promise.resolve(void 0);
156
143
  }
157
144
  /**
158
145
  * A fast way to retrieve resource ID for any resource definition.
@@ -183,9 +170,9 @@ class ResourcesControl {
183
170
  serialization: "full",
184
171
  ...query
185
172
  }).then((resources) => {
186
- if (resources) {
173
+ if ((requestOptions == null ? void 0 : requestOptions.cache) && resources) {
187
174
  for (const x of resources) {
188
- this.cache.add("resource.item", CancelablePromise.resolve(x), {
175
+ this.cache.add("resource.item", Promise.resolve(x), {
189
176
  id: x.resource.id
190
177
  });
191
178
  }
@@ -201,7 +188,7 @@ class ResourcesControl {
201
188
  if (child) {
202
189
  return this.getOne(child.resource.parent.id, requestOptions);
203
190
  }
204
- return CancelablePromise.resolve(void 0);
191
+ return Promise.resolve(void 0);
205
192
  });
206
193
  }
207
194
  getChildrenOf(resource, requestOptions) {
@@ -231,18 +218,16 @@ class ResourcesControl {
231
218
  });
232
219
  }
233
220
  _getChildrenOf(parent, requestOptions, _items = []) {
234
- return this.connector.get(
235
- "resource.collection",
236
- { cache: true, ...requestOptions },
237
- {
238
- parent
239
- }
240
- ).then((items) => {
221
+ return this.connector.get("resource.collection", requestOptions, {
222
+ parent
223
+ }).then((items) => {
241
224
  const recursivePromises = [];
242
225
  for (const item of items) {
243
- this.cache.add("resource.item", CancelablePromise.resolve(item), {
244
- id: item.resource.id
245
- });
226
+ if (requestOptions == null ? void 0 : requestOptions.cache) {
227
+ this.cache.add("resource.item", Promise.resolve(item), {
228
+ id: item.resource.id
229
+ });
230
+ }
246
231
  _items.push(item);
247
232
  if ((requestOptions == null ? void 0 : requestOptions.recursive) && item.resource.children) {
248
233
  recursivePromises.push(
@@ -251,7 +236,7 @@ class ResourcesControl {
251
236
  }
252
237
  }
253
238
  if (recursivePromises.length) {
254
- return CancelablePromise.all(recursivePromises).then(() => {
239
+ return Promise.all(recursivePromises).then(() => {
255
240
  return _items;
256
241
  });
257
242
  }
@@ -259,10 +244,11 @@ class ResourcesControl {
259
244
  });
260
245
  }
261
246
  async _cleanResourceItemCache(id) {
247
+ var _a;
262
248
  const all = this.cache.all();
263
249
  const toDelete = [];
264
250
  for (const c of all) {
265
- const cid = c.options && c.options.id;
251
+ const cid = (_a = c.props) == null ? void 0 : _a.id;
266
252
  if (["resource.item", "resource"].includes(c.key) && cid !== void 0) {
267
253
  if (typeof cid === "number") {
268
254
  if (cid === id) {
@@ -281,18 +267,7 @@ class ResourcesControl {
281
267
  }
282
268
  }
283
269
  _fetchResourceById(id, requestOptions) {
284
- const promise = () => this.connector.get("resource.item", requestOptions, { id });
285
- if (requestOptions == null ? void 0 : requestOptions.cache) {
286
- return this.cache.add("resource.item", promise, {
287
- id
288
- }).catch((er) => {
289
- if (!(er instanceof ResourceNotFoundError)) {
290
- throw er;
291
- }
292
- return void 0;
293
- });
294
- }
295
- return promise();
270
+ return this.connector.get("resource.item", requestOptions, { id });
296
271
  }
297
272
  _fetchResourceBy(resource, requestOptions) {
298
273
  return this.getMany(resource, requestOptions).then((resources) => {
@@ -300,7 +275,7 @@ class ResourcesControl {
300
275
  });
301
276
  }
302
277
  _resourceCacheFilter(resource) {
303
- return CancelablePromise.all(this.cache.matchAll("resource.item")).then(
278
+ return Promise.all(this.cache.matchAll("resource.item")).then(
304
279
  (resources) => {
305
280
  const items = [];
306
281
  resources.filter((x) => {
@@ -344,6 +319,13 @@ function removeConnector(connector) {
344
319
  }
345
320
  }
346
321
 
322
+ class AbortError extends Error {
323
+ constructor(message = "AbortError") {
324
+ super(message);
325
+ this.name = "AbortError";
326
+ }
327
+ }
328
+
347
329
  var __defProp$1 = Object.defineProperty;
348
330
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
349
331
  var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -369,59 +351,54 @@ function template(str, data) {
369
351
  });
370
352
  }
371
353
 
372
- function apiRequest(opt) {
373
- const params = opt.params;
374
- return new CancelablePromise((resolve, reject) => {
375
- return opt.connector.connect().then((apiItems) => {
376
- let apiItem = apiItems && apiItems[opt.name];
377
- if (apiItem) {
378
- apiItem = [...apiItem];
379
- let url = apiItem.shift();
380
- if (apiItem.length) {
381
- const replaceParams = {};
382
- for (let fry = 0; fry < apiItem.length; fry++) {
383
- const arg = apiItem[fry];
384
- replaceParams[fry] = "{" + arg + "}";
385
- if (params[arg] === void 0) {
386
- throw new Error(
387
- "`" + arg + "` url api argument is not specified"
388
- );
389
- }
390
- }
391
- if (url) {
392
- url = template(url, replaceParams);
393
- }
354
+ async function apiRequest(opt) {
355
+ const { params, name, connector, requestOptions } = opt;
356
+ const apiItems = await connector.connect();
357
+ let apiItem = apiItems && apiItems[name];
358
+ if (apiItem) {
359
+ apiItem = [...apiItem];
360
+ let url = apiItem.shift();
361
+ if (apiItem.length) {
362
+ const replaceParams = {};
363
+ for (let fry = 0; fry < apiItem.length; fry++) {
364
+ const arg = apiItem[fry];
365
+ replaceParams[fry] = `{${arg}}`;
366
+ if (params[arg] === void 0) {
367
+ throw new Error(`\`${arg}\` URL API argument is not specified`);
394
368
  }
395
- if (params) {
396
- const paramArray = [];
397
- const paramList = params.paramList;
398
- if (Array.isArray(paramList)) {
399
- delete params.paramList;
400
- paramList.forEach((x) => {
401
- paramArray.push(`${x[0]}=${x[1]}`);
402
- });
403
- }
404
- for (const p in params) {
405
- if (apiItem.indexOf(p) === -1) {
406
- paramArray.push(`${p}=${params[p]}`);
407
- }
408
- }
409
- if (paramArray.length) {
410
- url = url + "?" + paramArray.join("&");
411
- }
412
- }
413
- if (url) {
414
- resolve(opt.connector.makeQuery(url, params, opt.requestOptions));
415
- } else {
416
- reject(new Error("request url is not set"));
369
+ }
370
+ if (url) {
371
+ url = template(url, replaceParams);
372
+ }
373
+ }
374
+ if (params) {
375
+ const paramArray = [];
376
+ const paramList = params.paramList;
377
+ if (Array.isArray(paramList)) {
378
+ paramList.forEach(([key, value]) => {
379
+ paramArray.push(`${key}=${value}`);
380
+ });
381
+ }
382
+ for (const p in params) {
383
+ if (apiItem.indexOf(p) === -1) {
384
+ paramArray.push(`${p}=${params[p]}`);
417
385
  }
418
- } else {
419
- resolve(void 0);
420
386
  }
421
- }).catch((er) => {
422
- reject(er);
423
- });
424
- });
387
+ if (paramArray.length) {
388
+ url = `${url}?${paramArray.join("&")}`;
389
+ }
390
+ }
391
+ if (url) {
392
+ return connector.makeQuery(url, params, {
393
+ cacheName: name,
394
+ ...requestOptions
395
+ });
396
+ } else {
397
+ throw new Error("Request URL is not set");
398
+ }
399
+ } else {
400
+ return void 0;
401
+ }
425
402
  }
426
403
 
427
404
  function isError(error) {
@@ -556,6 +533,7 @@ var __defProp = Object.defineProperty;
556
533
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
557
534
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
558
535
  let ID = 0;
536
+ let REQUEST_ID = 0;
559
537
  class NgwConnector {
560
538
  constructor(options) {
561
539
  this.options = options;
@@ -566,7 +544,7 @@ class NgwConnector {
566
544
  __publicField(this, "cache");
567
545
  __publicField(this, "withCredentials");
568
546
  __publicField(this, "routeStr", "/api/component/pyramid/route");
569
- __publicField(this, "activeRequests", []);
547
+ __publicField(this, "activeRequests", {});
570
548
  __publicField(this, "requestTransform");
571
549
  const exist = findConnector(options);
572
550
  this.cache = new Cache({ namespace: options.cacheId });
@@ -626,31 +604,27 @@ class NgwConnector {
626
604
  * .catch((er) => console.log('Connection problem', er));
627
605
  * ```
628
606
  */
629
- connect() {
607
+ async connect() {
630
608
  const auth = this.options.auth;
631
- const makeConnect = () => new CancelablePromise((resolve, reject) => {
632
- const makeQuery = () => {
633
- return this.makeQuery(this.routeStr, {}, {}).then((route) => {
634
- resolve(route);
635
- }).catch((er) => {
636
- reject(er);
637
- });
638
- };
639
- if (auth) {
640
- const { login, password } = auth;
641
- if (login && password) {
642
- return this._login({ login, password }).then(() => {
643
- return makeQuery();
644
- }).catch((er) => reject(er));
609
+ if (auth) {
610
+ const { login, password } = auth;
611
+ if (login && password) {
612
+ await this._login({ login, password });
613
+ }
614
+ }
615
+ return await this.makeQuery(
616
+ this.routeStr,
617
+ {},
618
+ {
619
+ cacheName: "route",
620
+ cache: true,
621
+ cacheProps: {
622
+ id: this.id,
623
+ auth,
624
+ baseUrl: this.options.baseUrl
645
625
  }
646
626
  }
647
- return makeQuery();
648
- });
649
- return this.cache.add("route", makeConnect, {
650
- id: this.id,
651
- auth,
652
- baseUrl: this.options.baseUrl
653
- });
627
+ );
654
628
  }
655
629
  /**
656
630
  * Quick way to change NextGIS Web user.
@@ -672,16 +646,15 @@ class NgwConnector {
672
646
  this.clearCache();
673
647
  this.emitter.emit("logout");
674
648
  }
675
- getUserInfo(credentials, options) {
649
+ async getUserInfo(credentials, options) {
676
650
  if (this.user && this.user.id) {
677
- return CancelablePromise.resolve(this.user);
651
+ return this.user;
678
652
  }
679
653
  if (credentials) {
680
654
  this.options.auth = credentials;
681
655
  }
682
656
  const options_ = {
683
657
  headers: this.getAuthorizationHeaders(credentials),
684
- // withCredentials: true
685
658
  ...options
686
659
  };
687
660
  return this.makeQuery(
@@ -697,7 +670,7 @@ class NgwConnector {
697
670
  const client = this.makeClientId(credentials);
698
671
  if (client) {
699
672
  return {
700
- Authorization: "Basic " + client
673
+ Authorization: `Basic ${client}`
701
674
  };
702
675
  }
703
676
  }
@@ -705,21 +678,22 @@ class NgwConnector {
705
678
  credentials = credentials || this.options.auth;
706
679
  if (credentials) {
707
680
  const { login, password } = credentials;
708
- const str = unescape(encodeURIComponent(`${login}:${password}`));
681
+ const str = `${login}:${password}`;
682
+ const encodedStr = encodeURIComponent(str);
709
683
  {
710
- return Buffer.from(str).toString("base64");
684
+ return Buffer.from(encodedStr).toString("base64");
711
685
  }
712
686
  }
713
687
  }
714
688
  /** Stop all api requests */
715
689
  abort() {
716
- for (const req of this.activeRequests) {
717
- req.cancel();
690
+ for (const abortController of Object.values(this.activeRequests)) {
691
+ abortController.abort();
718
692
  }
719
- this.activeRequests = [];
693
+ this.activeRequests = {};
720
694
  }
721
695
  getActiveApiRequests() {
722
- return [...this.activeRequests];
696
+ return { ...this.activeRequests };
723
697
  }
724
698
  /**
725
699
  * Send request to NGW api router.
@@ -751,28 +725,10 @@ class NgwConnector {
751
725
  * ```
752
726
  */
753
727
  apiRequest(name, params_ = {}, requestOptions = {}) {
754
- var _a, _b;
755
- requestOptions = {
756
- withCredentials: this.withCredentials,
757
- ...requestOptions
758
- };
759
- const { method, headers, withCredentials, responseType } = requestOptions;
728
+ var _a;
760
729
  params_ = (_a = requestOptions.params) != null ? _a : params_;
761
730
  const params = utils.objectRemoveEmpty(params_);
762
- const makeApiRequest = () => apiRequest({ name, params, requestOptions, connector: this });
763
- if (requestOptions.cache && method === "GET") {
764
- return this.cache.add(name, makeApiRequest, {
765
- params,
766
- ...utils.objectRemoveEmpty({
767
- headers,
768
- withCredentials,
769
- responseType,
770
- baseUrl: this.options.baseUrl,
771
- userId: (_b = this.user) == null ? void 0 : _b.id
772
- })
773
- });
774
- }
775
- return makeApiRequest();
731
+ return apiRequest({ name, params, requestOptions, connector: this });
776
732
  }
777
733
  /**
778
734
  * Shortcut method for send POST request to NGW.
@@ -862,17 +818,67 @@ class NgwConnector {
862
818
  * @param params - Query params
863
819
  * @param options - Request options
864
820
  */
865
- makeQuery(url, params, options = {}) {
821
+ async makeQuery(url, params, options = {}) {
822
+ var _a;
866
823
  url = (this.options.baseUrl ? this.options.baseUrl : "") + url;
867
- if (url) {
868
- if (params) {
869
- url = template(url, params);
870
- }
871
- url = encodeURI(utils.fixUrlStr(url));
872
- return this._loadData(url, options);
873
- } else {
824
+ if (!url) {
874
825
  throw new Error("Empty `url` not allowed");
875
826
  }
827
+ if (params) {
828
+ const { paramList, ...restParams } = params;
829
+ url = template(url, restParams);
830
+ }
831
+ url = encodeURI(utils.fixUrlStr(url));
832
+ options = { withCredentials: this.withCredentials, ...options };
833
+ const {
834
+ cache,
835
+ signal: externalSignal,
836
+ method = "GET",
837
+ headers,
838
+ cacheName,
839
+ cacheProps,
840
+ responseType,
841
+ withCredentials
842
+ } = options;
843
+ const internalAbortController = new AbortController();
844
+ const internalSignal = internalAbortController.signal;
845
+ if (externalSignal) {
846
+ if (externalSignal.aborted) {
847
+ throw new AbortError();
848
+ }
849
+ externalSignal.addEventListener("abort", () => {
850
+ internalAbortController.abort();
851
+ });
852
+ }
853
+ options.signal = internalSignal;
854
+ const createPromise = async () => {
855
+ const id = REQUEST_ID++;
856
+ this.activeRequests[id] = internalAbortController;
857
+ try {
858
+ return this._loadData(url, options);
859
+ } finally {
860
+ this._cleanActiveRequest(id);
861
+ }
862
+ };
863
+ if (cache && method === "GET") {
864
+ const cacheOptions = cacheProps ? cacheProps : {
865
+ ...utils.objectRemoveEmpty({
866
+ headers,
867
+ withCredentials,
868
+ responseType,
869
+ baseUrl: this.options.baseUrl,
870
+ userId: (_a = this.user) == null ? void 0 : _a.id
871
+ }),
872
+ params
873
+ };
874
+ return this.cache.add(
875
+ cacheName || url,
876
+ createPromise,
877
+ cacheOptions,
878
+ false
879
+ );
880
+ }
881
+ return createPromise();
876
882
  }
877
883
  // -------------------------------------------------------------------------
878
884
  // Resource Methods
@@ -954,10 +960,8 @@ class NgwConnector {
954
960
  */
955
961
  _loadData(url, options) {
956
962
  options.responseType = options.responseType || "json";
957
- if (options.signal && options.signal.aborted) {
958
- return CancelablePromise.reject(new CancelablePromise.CancelError());
959
- }
960
- const request = new CancelablePromise((resolve, reject, onCancel) => {
963
+ return new Promise((resolve, reject) => {
964
+ var _a;
961
965
  if (this.user) {
962
966
  options = options || {};
963
967
  options.headers = {
@@ -970,13 +974,18 @@ class NgwConnector {
970
974
  url = transUrl;
971
975
  options = transOptions;
972
976
  }
973
- loadData(url, resolve, options, reject, onCancel);
974
- }).then((resp) => {
975
- this._cleanActiveRequests(request);
976
- return resp;
977
+ let runOnAbort = void 0;
978
+ loadData(url, resolve, options, reject, (handler) => {
979
+ runOnAbort = handler;
980
+ });
981
+ (_a = options.signal) == null ? void 0 : _a.addEventListener("abort", () => {
982
+ if (runOnAbort !== void 0) {
983
+ runOnAbort();
984
+ }
985
+ reject(new AbortError());
986
+ });
977
987
  }).catch((httpError) => {
978
- this._cleanActiveRequests(request);
979
- if (httpError instanceof CancelablePromise.CancelError) ; else {
988
+ if (httpError.name !== "AbortError") {
980
989
  {
981
990
  console.warn("DEV WARN", httpError);
982
991
  }
@@ -985,32 +994,23 @@ class NgwConnector {
985
994
  throw er;
986
995
  }
987
996
  }
997
+ throw httpError;
988
998
  });
989
- if (options.signal && typeof options.signal.addEventListener === "function") {
990
- options.signal.addEventListener("abort", () => {
991
- request.cancel();
992
- this._cleanActiveRequests(request);
993
- });
994
- }
995
- this.activeRequests.push(request);
996
- return request;
997
999
  }
998
- _login(credentials, options) {
999
- return this.getUserInfo(credentials, options).then((data) => {
1000
+ async _login(credentials, options) {
1001
+ try {
1002
+ const data = await this.getUserInfo(credentials, options);
1000
1003
  this.user = data;
1001
1004
  this.emitter.emit("login", data);
1002
1005
  return data;
1003
- }).catch((er) => {
1006
+ } catch (er) {
1004
1007
  this.emitter.emit("login:error", er);
1005
1008
  throw er;
1006
- });
1007
- }
1008
- _cleanActiveRequests(request) {
1009
- const activeRequestIndex = this.activeRequests.indexOf(request);
1010
- if (activeRequestIndex !== -1) {
1011
- this.activeRequests.splice(activeRequestIndex, 1);
1012
1009
  }
1013
1010
  }
1011
+ _cleanActiveRequest(requestId) {
1012
+ delete this.activeRequests[requestId];
1013
+ }
1014
1014
  _handleHttpError(er) {
1015
1015
  if (er) {
1016
1016
  if (er instanceof NgwError) {