@nextgis/ngw-connector 2.3.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.3.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,36 +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
- 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);
111
+ }
112
+ return Promise.resolve(void 0);
123
113
  }
124
114
  getOneOrFail(resource, requestOptions) {
125
115
  return this.getOne(resource, requestOptions).then((res) => {
@@ -141,7 +131,7 @@ class ResourcesControl {
141
131
  */
142
132
  getId(resource, requestOptions) {
143
133
  if (typeof resource === "number") {
144
- return CancelablePromise.resolve(resource);
134
+ return Promise.resolve(resource);
145
135
  } else if (typeof resource === "string" || isObject(resource)) {
146
136
  return this.getOne(resource, requestOptions).then((res) => {
147
137
  if (res) {
@@ -149,7 +139,7 @@ class ResourcesControl {
149
139
  }
150
140
  });
151
141
  }
152
- return CancelablePromise.resolve(void 0);
142
+ return Promise.resolve(void 0);
153
143
  }
154
144
  /**
155
145
  * A fast way to retrieve resource ID for any resource definition.
@@ -180,9 +170,9 @@ class ResourcesControl {
180
170
  serialization: "full",
181
171
  ...query
182
172
  }).then((resources) => {
183
- if (resources) {
173
+ if ((requestOptions == null ? void 0 : requestOptions.cache) && resources) {
184
174
  for (const x of resources) {
185
- this.cache.add("resource.item", CancelablePromise.resolve(x), {
175
+ this.cache.add("resource.item", Promise.resolve(x), {
186
176
  id: x.resource.id
187
177
  });
188
178
  }
@@ -198,7 +188,7 @@ class ResourcesControl {
198
188
  if (child) {
199
189
  return this.getOne(child.resource.parent.id, requestOptions);
200
190
  }
201
- return CancelablePromise.resolve(void 0);
191
+ return Promise.resolve(void 0);
202
192
  });
203
193
  }
204
194
  getChildrenOf(resource, requestOptions) {
@@ -228,18 +218,16 @@ class ResourcesControl {
228
218
  });
229
219
  }
230
220
  _getChildrenOf(parent, requestOptions, _items = []) {
231
- return this.connector.get(
232
- "resource.collection",
233
- { cache: true, ...requestOptions },
234
- {
235
- parent
236
- }
237
- ).then((items) => {
221
+ return this.connector.get("resource.collection", requestOptions, {
222
+ parent
223
+ }).then((items) => {
238
224
  const recursivePromises = [];
239
225
  for (const item of items) {
240
- this.cache.add("resource.item", CancelablePromise.resolve(item), {
241
- id: item.resource.id
242
- });
226
+ if (requestOptions == null ? void 0 : requestOptions.cache) {
227
+ this.cache.add("resource.item", Promise.resolve(item), {
228
+ id: item.resource.id
229
+ });
230
+ }
243
231
  _items.push(item);
244
232
  if ((requestOptions == null ? void 0 : requestOptions.recursive) && item.resource.children) {
245
233
  recursivePromises.push(
@@ -248,7 +236,7 @@ class ResourcesControl {
248
236
  }
249
237
  }
250
238
  if (recursivePromises.length) {
251
- return CancelablePromise.all(recursivePromises).then(() => {
239
+ return Promise.all(recursivePromises).then(() => {
252
240
  return _items;
253
241
  });
254
242
  }
@@ -256,10 +244,11 @@ class ResourcesControl {
256
244
  });
257
245
  }
258
246
  async _cleanResourceItemCache(id) {
247
+ var _a;
259
248
  const all = this.cache.all();
260
249
  const toDelete = [];
261
250
  for (const c of all) {
262
- const cid = c.options && c.options.id;
251
+ const cid = (_a = c.props) == null ? void 0 : _a.id;
263
252
  if (["resource.item", "resource"].includes(c.key) && cid !== void 0) {
264
253
  if (typeof cid === "number") {
265
254
  if (cid === id) {
@@ -278,15 +267,7 @@ class ResourcesControl {
278
267
  }
279
268
  }
280
269
  _fetchResourceById(id, requestOptions) {
281
- const promise = () => this.connector.get("resource.item", requestOptions, { id });
282
- return this.cache.add("resource.item", promise, {
283
- id
284
- }).catch((er) => {
285
- if (!(er instanceof ResourceNotFoundError)) {
286
- throw er;
287
- }
288
- return void 0;
289
- });
270
+ return this.connector.get("resource.item", requestOptions, { id });
290
271
  }
291
272
  _fetchResourceBy(resource, requestOptions) {
292
273
  return this.getMany(resource, requestOptions).then((resources) => {
@@ -294,7 +275,7 @@ class ResourcesControl {
294
275
  });
295
276
  }
296
277
  _resourceCacheFilter(resource) {
297
- return CancelablePromise.all(this.cache.matchAll("resource.item")).then(
278
+ return Promise.all(this.cache.matchAll("resource.item")).then(
298
279
  (resources) => {
299
280
  const items = [];
300
281
  resources.filter((x) => {
@@ -338,6 +319,13 @@ function removeConnector(connector) {
338
319
  }
339
320
  }
340
321
 
322
+ class AbortError extends Error {
323
+ constructor(message = "AbortError") {
324
+ super(message);
325
+ this.name = "AbortError";
326
+ }
327
+ }
328
+
341
329
  var __defProp$1 = Object.defineProperty;
342
330
  var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
343
331
  var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -363,59 +351,54 @@ function template(str, data) {
363
351
  });
364
352
  }
365
353
 
366
- function apiRequest(opt) {
367
- const params = opt.params;
368
- return new CancelablePromise((resolve, reject) => {
369
- opt.connector.connect().then((apiItems) => {
370
- let apiItem = apiItems && apiItems[opt.name];
371
- if (apiItem) {
372
- apiItem = [...apiItem];
373
- let url = apiItem.shift();
374
- if (apiItem.length) {
375
- const replaceParams = {};
376
- for (let fry = 0; fry < apiItem.length; fry++) {
377
- const arg = apiItem[fry];
378
- replaceParams[fry] = "{" + arg + "}";
379
- if (params[arg] === void 0) {
380
- throw new Error(
381
- "`" + arg + "` url api argument is not specified"
382
- );
383
- }
384
- }
385
- if (url) {
386
- url = template(url, replaceParams);
387
- }
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`);
388
368
  }
389
- if (params) {
390
- const paramArray = [];
391
- const paramList = params.paramList;
392
- if (Array.isArray(paramList)) {
393
- delete params.paramList;
394
- paramList.forEach((x) => {
395
- paramArray.push(`${x[0]}=${x[1]}`);
396
- });
397
- }
398
- for (const p in params) {
399
- if (apiItem.indexOf(p) === -1) {
400
- paramArray.push(`${p}=${params[p]}`);
401
- }
402
- }
403
- if (paramArray.length) {
404
- url = url + "?" + paramArray.join("&");
405
- }
406
- }
407
- if (url) {
408
- resolve(opt.connector.makeQuery(url, params, opt.requestOptions));
409
- } else {
410
- 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]}`);
411
385
  }
412
- } else {
413
- resolve(void 0);
414
386
  }
415
- }).catch((er) => {
416
- reject(er);
417
- });
418
- });
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
+ }
419
402
  }
420
403
 
421
404
  function isError(error) {
@@ -550,6 +533,7 @@ var __defProp = Object.defineProperty;
550
533
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
551
534
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
552
535
  let ID = 0;
536
+ let REQUEST_ID = 0;
553
537
  class NgwConnector {
554
538
  constructor(options) {
555
539
  this.options = options;
@@ -559,7 +543,7 @@ class NgwConnector {
559
543
  __publicField(this, "resources");
560
544
  __publicField(this, "cache");
561
545
  __publicField(this, "routeStr", "/api/component/pyramid/route");
562
- __publicField(this, "activeRequests", []);
546
+ __publicField(this, "activeRequests", {});
563
547
  __publicField(this, "requestTransform");
564
548
  const exist = findConnector(options);
565
549
  this.cache = new Cache({ namespace: options.cacheId });
@@ -615,31 +599,27 @@ class NgwConnector {
615
599
  * .catch((er) => console.log('Connection problem', er));
616
600
  * ```
617
601
  */
618
- connect() {
602
+ async connect() {
619
603
  const auth = this.options.auth;
620
- const makeConnect = () => new CancelablePromise((resolve, reject) => {
621
- const makeQuery = () => {
622
- return this.makeQuery(this.routeStr, {}, {}).then((route) => {
623
- resolve(route);
624
- }).catch((er) => {
625
- reject(er);
626
- });
627
- };
628
- if (auth) {
629
- const { login, password } = auth;
630
- if (login && password) {
631
- return this._login({ login, password }).then(() => {
632
- return makeQuery();
633
- }).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
634
620
  }
635
621
  }
636
- return makeQuery();
637
- });
638
- return this.cache.add("route", makeConnect, {
639
- id: this.id,
640
- auth,
641
- baseUrl: this.options.baseUrl
642
- });
622
+ );
643
623
  }
644
624
  /**
645
625
  * Quick way to change NextGIS Web user.
@@ -661,16 +641,15 @@ class NgwConnector {
661
641
  this.clearCache();
662
642
  this.emitter.emit("logout");
663
643
  }
664
- getUserInfo(credentials, options) {
644
+ async getUserInfo(credentials, options) {
665
645
  if (this.user && this.user.id) {
666
- return CancelablePromise.resolve(this.user);
646
+ return this.user;
667
647
  }
668
648
  if (credentials) {
669
649
  this.options.auth = credentials;
670
650
  }
671
651
  const options_ = {
672
652
  headers: this.getAuthorizationHeaders(credentials),
673
- // withCredentials: true
674
653
  ...options
675
654
  };
676
655
  return this.makeQuery(
@@ -686,7 +665,7 @@ class NgwConnector {
686
665
  const client = this.makeClientId(credentials);
687
666
  if (client) {
688
667
  return {
689
- Authorization: "Basic " + client
668
+ Authorization: `Basic ${client}`
690
669
  };
691
670
  }
692
671
  }
@@ -694,21 +673,22 @@ class NgwConnector {
694
673
  credentials = credentials || this.options.auth;
695
674
  if (credentials) {
696
675
  const { login, password } = credentials;
697
- const str = unescape(encodeURIComponent(`${login}:${password}`));
676
+ const str = `${login}:${password}`;
677
+ const encodedStr = encodeURIComponent(str);
698
678
  {
699
- return Buffer.from(str).toString("base64");
679
+ return Buffer.from(encodedStr).toString("base64");
700
680
  }
701
681
  }
702
682
  }
703
683
  /** Stop all api requests */
704
684
  abort() {
705
- for (const req of this.activeRequests) {
706
- req.cancel();
685
+ for (const abortController of Object.values(this.activeRequests)) {
686
+ abortController.abort();
707
687
  }
708
- this.activeRequests = [];
688
+ this.activeRequests = {};
709
689
  }
710
690
  getActiveApiRequests() {
711
- return [...this.activeRequests];
691
+ return { ...this.activeRequests };
712
692
  }
713
693
  /**
714
694
  * Send request to NGW api router.
@@ -740,24 +720,10 @@ class NgwConnector {
740
720
  * ```
741
721
  */
742
722
  apiRequest(name, params_ = {}, requestOptions = {}) {
743
- var _a, _b;
744
- const { method, headers, withCredentials, responseType } = requestOptions;
723
+ var _a;
745
724
  params_ = (_a = requestOptions.params) != null ? _a : params_;
746
725
  const params = utils.objectRemoveEmpty(params_);
747
- const makeApiRequest = () => apiRequest({ name, params, requestOptions, connector: this });
748
- if (requestOptions.cache && method === "GET") {
749
- return this.cache.add(name, makeApiRequest, {
750
- params,
751
- ...utils.objectRemoveEmpty({
752
- headers,
753
- withCredentials,
754
- responseType,
755
- baseUrl: this.options.baseUrl,
756
- userId: (_b = this.user) == null ? void 0 : _b.id
757
- })
758
- });
759
- }
760
- return makeApiRequest();
726
+ return apiRequest({ name, params, requestOptions, connector: this });
761
727
  }
762
728
  /**
763
729
  * Shortcut method for send POST request to NGW.
@@ -847,17 +813,66 @@ class NgwConnector {
847
813
  * @param params - Query params
848
814
  * @param options - Request options
849
815
  */
850
- makeQuery(url, params, options = {}) {
816
+ async makeQuery(url, params, options = {}) {
817
+ var _a;
851
818
  url = (this.options.baseUrl ? this.options.baseUrl : "") + url;
852
- if (url) {
853
- if (params) {
854
- url = template(url, params);
855
- }
856
- url = encodeURI(utils.fixUrlStr(url));
857
- return this._loadData(url, options);
858
- } else {
819
+ if (!url) {
859
820
  throw new Error("Empty `url` not allowed");
860
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();
861
876
  }
862
877
  // -------------------------------------------------------------------------
863
878
  // Resource Methods
@@ -939,10 +954,8 @@ class NgwConnector {
939
954
  */
940
955
  _loadData(url, options) {
941
956
  options.responseType = options.responseType || "json";
942
- if (options.signal && options.signal.aborted) {
943
- return CancelablePromise.reject(new CancelablePromise.CancelError());
944
- }
945
- const request = new CancelablePromise((resolve, reject, onCancel) => {
957
+ return new Promise((resolve, reject) => {
958
+ var _a;
946
959
  if (this.user) {
947
960
  options = options || {};
948
961
  options.headers = {
@@ -955,13 +968,18 @@ class NgwConnector {
955
968
  url = transUrl;
956
969
  options = transOptions;
957
970
  }
958
- loadData(url, resolve, options, reject, onCancel);
959
- }).then((resp) => {
960
- this._cleanActiveRequests(request);
961
- 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
+ });
962
981
  }).catch((httpError) => {
963
- this._cleanActiveRequests(request);
964
- if (httpError instanceof CancelablePromise.CancelError) ; else {
982
+ if (httpError.name !== "AbortError") {
965
983
  {
966
984
  console.warn("DEV WARN", httpError);
967
985
  }
@@ -970,32 +988,23 @@ class NgwConnector {
970
988
  throw er;
971
989
  }
972
990
  }
991
+ throw httpError;
973
992
  });
974
- if (options.signal && typeof options.signal.addEventListener === "function") {
975
- options.signal.addEventListener("abort", () => {
976
- request.cancel();
977
- this._cleanActiveRequests(request);
978
- });
979
- }
980
- this.activeRequests.push(request);
981
- return request;
982
993
  }
983
- _login(credentials, options) {
984
- return this.getUserInfo(credentials, options).then((data) => {
994
+ async _login(credentials, options) {
995
+ try {
996
+ const data = await this.getUserInfo(credentials, options);
985
997
  this.user = data;
986
998
  this.emitter.emit("login", data);
987
999
  return data;
988
- }).catch((er) => {
1000
+ } catch (er) {
989
1001
  this.emitter.emit("login:error", er);
990
1002
  throw er;
991
- });
992
- }
993
- _cleanActiveRequests(request) {
994
- const activeRequestIndex = this.activeRequests.indexOf(request);
995
- if (activeRequestIndex !== -1) {
996
- this.activeRequests.splice(activeRequestIndex, 1);
997
1003
  }
998
1004
  }
1005
+ _cleanActiveRequest(requestId) {
1006
+ delete this.activeRequests[requestId];
1007
+ }
999
1008
  _handleHttpError(er) {
1000
1009
  if (er) {
1001
1010
  if (er instanceof NgwError) {