@nextgis/ngw-connector 2.4.0 → 3.0.0-alpha.0

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.4.0; author: NextGIS */
1
+ /** Bundle of @nextgis/ngw-connector; version: 3.0.0-alpha.0; 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
- }
394
- }
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
- }
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`);
412
368
  }
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;
@@ -565,7 +543,7 @@ class NgwConnector {
565
543
  __publicField(this, "resources");
566
544
  __publicField(this, "cache");
567
545
  __publicField(this, "routeStr", "/api/component/pyramid/route");
568
- __publicField(this, "activeRequests", []);
546
+ __publicField(this, "activeRequests", {});
569
547
  __publicField(this, "requestTransform");
570
548
  const exist = findConnector(options);
571
549
  this.cache = new Cache({ namespace: options.cacheId });
@@ -621,31 +599,27 @@ class NgwConnector {
621
599
  * .catch((er) => console.log('Connection problem', er));
622
600
  * ```
623
601
  */
624
- connect() {
602
+ async connect() {
625
603
  const auth = this.options.auth;
626
- const makeConnect = () => new CancelablePromise((resolve, reject) => {
627
- const makeQuery = () => {
628
- return this.makeQuery(this.routeStr, {}, {}).then((route) => {
629
- resolve(route);
630
- }).catch((er) => {
631
- reject(er);
632
- });
633
- };
634
- if (auth) {
635
- const { login, password } = auth;
636
- if (login && password) {
637
- return this._login({ login, password }).then(() => {
638
- return makeQuery();
639
- }).catch((er) => reject(er));
604
+ if (auth) {
605
+ const { login, password } = auth;
606
+ if (login && password) {
607
+ await this._login({ login, password });
608
+ }
609
+ }
610
+ return await this.makeQuery(
611
+ this.routeStr,
612
+ {},
613
+ {
614
+ cacheName: "route",
615
+ cache: true,
616
+ cacheProps: {
617
+ id: this.id,
618
+ auth,
619
+ baseUrl: this.options.baseUrl
640
620
  }
641
621
  }
642
- return makeQuery();
643
- });
644
- return this.cache.add("route", makeConnect, {
645
- id: this.id,
646
- auth,
647
- baseUrl: this.options.baseUrl
648
- });
622
+ );
649
623
  }
650
624
  /**
651
625
  * Quick way to change NextGIS Web user.
@@ -667,16 +641,15 @@ class NgwConnector {
667
641
  this.clearCache();
668
642
  this.emitter.emit("logout");
669
643
  }
670
- getUserInfo(credentials, options) {
644
+ async getUserInfo(credentials, options) {
671
645
  if (this.user && this.user.id) {
672
- return CancelablePromise.resolve(this.user);
646
+ return this.user;
673
647
  }
674
648
  if (credentials) {
675
649
  this.options.auth = credentials;
676
650
  }
677
651
  const options_ = {
678
652
  headers: this.getAuthorizationHeaders(credentials),
679
- // withCredentials: true
680
653
  ...options
681
654
  };
682
655
  return this.makeQuery(
@@ -692,7 +665,7 @@ class NgwConnector {
692
665
  const client = this.makeClientId(credentials);
693
666
  if (client) {
694
667
  return {
695
- Authorization: "Basic " + client
668
+ Authorization: `Basic ${client}`
696
669
  };
697
670
  }
698
671
  }
@@ -700,21 +673,22 @@ class NgwConnector {
700
673
  credentials = credentials || this.options.auth;
701
674
  if (credentials) {
702
675
  const { login, password } = credentials;
703
- const str = unescape(encodeURIComponent(`${login}:${password}`));
676
+ const str = `${login}:${password}`;
677
+ const encodedStr = encodeURIComponent(str);
704
678
  {
705
- return Buffer.from(str).toString("base64");
679
+ return Buffer.from(encodedStr).toString("base64");
706
680
  }
707
681
  }
708
682
  }
709
683
  /** Stop all api requests */
710
684
  abort() {
711
- for (const req of this.activeRequests) {
712
- req.cancel();
685
+ for (const abortController of Object.values(this.activeRequests)) {
686
+ abortController.abort();
713
687
  }
714
- this.activeRequests = [];
688
+ this.activeRequests = {};
715
689
  }
716
690
  getActiveApiRequests() {
717
- return [...this.activeRequests];
691
+ return { ...this.activeRequests };
718
692
  }
719
693
  /**
720
694
  * Send request to NGW api router.
@@ -746,24 +720,10 @@ class NgwConnector {
746
720
  * ```
747
721
  */
748
722
  apiRequest(name, params_ = {}, requestOptions = {}) {
749
- var _a, _b;
750
- const { method, headers, withCredentials, responseType } = requestOptions;
723
+ var _a;
751
724
  params_ = (_a = requestOptions.params) != null ? _a : params_;
752
725
  const params = utils.objectRemoveEmpty(params_);
753
- const makeApiRequest = () => apiRequest({ name, params, requestOptions, connector: this });
754
- if (requestOptions.cache && method === "GET") {
755
- return this.cache.add(name, makeApiRequest, {
756
- params,
757
- ...utils.objectRemoveEmpty({
758
- headers,
759
- withCredentials,
760
- responseType,
761
- baseUrl: this.options.baseUrl,
762
- userId: (_b = this.user) == null ? void 0 : _b.id
763
- })
764
- });
765
- }
766
- return makeApiRequest();
726
+ return apiRequest({ name, params, requestOptions, connector: this });
767
727
  }
768
728
  /**
769
729
  * Shortcut method for send POST request to NGW.
@@ -853,17 +813,66 @@ class NgwConnector {
853
813
  * @param params - Query params
854
814
  * @param options - Request options
855
815
  */
856
- makeQuery(url, params, options = {}) {
816
+ async makeQuery(url, params, options = {}) {
817
+ var _a;
857
818
  url = (this.options.baseUrl ? this.options.baseUrl : "") + url;
858
- if (url) {
859
- if (params) {
860
- url = template(url, params);
861
- }
862
- url = encodeURI(utils.fixUrlStr(url));
863
- return this._loadData(url, options);
864
- } else {
819
+ if (!url) {
865
820
  throw new Error("Empty `url` not allowed");
866
821
  }
822
+ if (params) {
823
+ const { paramList, ...restParams } = params;
824
+ url = template(url, restParams);
825
+ }
826
+ url = encodeURI(utils.fixUrlStr(url));
827
+ const {
828
+ cache,
829
+ signal: externalSignal,
830
+ method = "GET",
831
+ headers,
832
+ cacheName,
833
+ cacheProps,
834
+ responseType,
835
+ withCredentials
836
+ } = options;
837
+ const internalAbortController = new AbortController();
838
+ const internalSignal = internalAbortController.signal;
839
+ if (externalSignal) {
840
+ if (externalSignal.aborted) {
841
+ throw new AbortError();
842
+ }
843
+ externalSignal.addEventListener("abort", () => {
844
+ internalAbortController.abort();
845
+ });
846
+ }
847
+ options.signal = internalSignal;
848
+ const createPromise = async () => {
849
+ const id = REQUEST_ID++;
850
+ this.activeRequests[id] = internalAbortController;
851
+ try {
852
+ return this._loadData(url, options);
853
+ } finally {
854
+ this._cleanActiveRequest(id);
855
+ }
856
+ };
857
+ if (cache && method === "GET") {
858
+ const cacheOptions = cacheProps ? cacheProps : {
859
+ ...utils.objectRemoveEmpty({
860
+ headers,
861
+ withCredentials,
862
+ responseType,
863
+ baseUrl: this.options.baseUrl,
864
+ userId: (_a = this.user) == null ? void 0 : _a.id
865
+ }),
866
+ params
867
+ };
868
+ return this.cache.add(
869
+ cacheName || url,
870
+ createPromise,
871
+ cacheOptions,
872
+ false
873
+ );
874
+ }
875
+ return createPromise();
867
876
  }
868
877
  // -------------------------------------------------------------------------
869
878
  // Resource Methods
@@ -945,10 +954,8 @@ class NgwConnector {
945
954
  */
946
955
  _loadData(url, options) {
947
956
  options.responseType = options.responseType || "json";
948
- if (options.signal && options.signal.aborted) {
949
- return CancelablePromise.reject(new CancelablePromise.CancelError());
950
- }
951
- const request = new CancelablePromise((resolve, reject, onCancel) => {
957
+ return new Promise((resolve, reject) => {
958
+ var _a;
952
959
  if (this.user) {
953
960
  options = options || {};
954
961
  options.headers = {
@@ -961,13 +968,18 @@ class NgwConnector {
961
968
  url = transUrl;
962
969
  options = transOptions;
963
970
  }
964
- loadData(url, resolve, options, reject, onCancel);
965
- }).then((resp) => {
966
- this._cleanActiveRequests(request);
967
- return resp;
971
+ let runOnAbort = void 0;
972
+ loadData(url, resolve, options, reject, (handler) => {
973
+ runOnAbort = handler;
974
+ });
975
+ (_a = options.signal) == null ? void 0 : _a.addEventListener("abort", () => {
976
+ if (runOnAbort !== void 0) {
977
+ runOnAbort();
978
+ }
979
+ reject(new AbortError());
980
+ });
968
981
  }).catch((httpError) => {
969
- this._cleanActiveRequests(request);
970
- if (httpError instanceof CancelablePromise.CancelError) ; else {
982
+ if (httpError.name !== "AbortError") {
971
983
  {
972
984
  console.warn("DEV WARN", httpError);
973
985
  }
@@ -976,32 +988,23 @@ class NgwConnector {
976
988
  throw er;
977
989
  }
978
990
  }
991
+ throw httpError;
979
992
  });
980
- if (options.signal && typeof options.signal.addEventListener === "function") {
981
- options.signal.addEventListener("abort", () => {
982
- request.cancel();
983
- this._cleanActiveRequests(request);
984
- });
985
- }
986
- this.activeRequests.push(request);
987
- return request;
988
993
  }
989
- _login(credentials, options) {
990
- return this.getUserInfo(credentials, options).then((data) => {
994
+ async _login(credentials, options) {
995
+ try {
996
+ const data = await this.getUserInfo(credentials, options);
991
997
  this.user = data;
992
998
  this.emitter.emit("login", data);
993
999
  return data;
994
- }).catch((er) => {
1000
+ } catch (er) {
995
1001
  this.emitter.emit("login:error", er);
996
1002
  throw er;
997
- });
998
- }
999
- _cleanActiveRequests(request) {
1000
- const activeRequestIndex = this.activeRequests.indexOf(request);
1001
- if (activeRequestIndex !== -1) {
1002
- this.activeRequests.splice(activeRequestIndex, 1);
1003
1003
  }
1004
1004
  }
1005
+ _cleanActiveRequest(requestId) {
1006
+ delete this.activeRequests[requestId];
1007
+ }
1005
1008
  _handleHttpError(er) {
1006
1009
  if (er) {
1007
1010
  if (er instanceof NgwError) {