@supersoniks/concorde 2.0.2 → 2.0.4

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.
Files changed (106) hide show
  1. package/README.md +1 -0
  2. package/concorde-core.bundle.js +748 -690
  3. package/concorde-core.es.js +3903 -3123
  4. package/core/_types/types.d.ts +2 -4
  5. package/core/components/functional/date/date.d.ts +4 -2
  6. package/core/components/functional/date/date.js +28 -13
  7. package/core/components/functional/fetch/fetch.d.ts +9 -10
  8. package/core/components/functional/fetch/fetch.js +21 -5
  9. package/core/components/functional/list/list.d.ts +7 -10
  10. package/core/components/functional/list/list.js +19 -4
  11. package/core/components/functional/queue/queue.d.ts +3 -2
  12. package/core/components/functional/queue/queue.js +71 -61
  13. package/core/components/functional/router/router.d.ts +1 -0
  14. package/core/components/functional/router/router.js +14 -3
  15. package/core/components/functional/sdui/sdui.d.ts +2 -7
  16. package/core/components/functional/submit/submit.js +11 -4
  17. package/core/components/ui/_css/scroll.js +13 -11
  18. package/core/components/ui/_css/size.js +1 -1
  19. package/core/components/ui/alert/alert.d.ts +14 -3
  20. package/core/components/ui/alert/alert.js +34 -4
  21. package/core/components/ui/badge/badge.js +10 -3
  22. package/core/components/ui/button/button.d.ts +19 -10
  23. package/core/components/ui/button/button.js +77 -22
  24. package/core/components/ui/captcha/captcha.d.ts +5 -4
  25. package/core/components/ui/captcha/captcha.js +33 -9
  26. package/core/components/ui/divider/divider.d.ts +2 -0
  27. package/core/components/ui/divider/divider.js +17 -2
  28. package/core/components/ui/form/checkbox/checkbox.d.ts +24 -9
  29. package/core/components/ui/form/checkbox/checkbox.js +4 -6
  30. package/core/components/ui/form/css/form-control.js +40 -7
  31. package/core/components/ui/form/fieldset/fieldset.d.ts +1 -0
  32. package/core/components/ui/form/fieldset/fieldset.js +14 -1
  33. package/core/components/ui/form/fieldset/legend-description.js +3 -3
  34. package/core/components/ui/form/fieldset/legend.js +2 -8
  35. package/core/components/ui/form/input/input.d.ts +4 -5
  36. package/core/components/ui/form/input/input.js +17 -13
  37. package/core/components/ui/form/input-autocomplete/input-autocomplete.d.ts +3 -5
  38. package/core/components/ui/form/input-autocomplete/input-autocomplete.js +9 -9
  39. package/core/components/ui/form/select/select.d.ts +4 -1
  40. package/core/components/ui/form/select/select.js +25 -18
  41. package/core/components/ui/form/textarea/textarea.d.ts +4 -5
  42. package/core/components/ui/form/textarea/textarea.js +19 -10
  43. package/core/components/ui/group/group.js +3 -3
  44. package/core/components/ui/icon/icon.js +2 -1
  45. package/core/components/ui/icon/icons.d.ts +0 -4
  46. package/core/components/ui/icon/icons.js +3 -16
  47. package/core/components/ui/link/link.d.ts +5 -2
  48. package/core/components/ui/link/link.js +31 -2
  49. package/core/components/ui/loader/loader.d.ts +4 -1
  50. package/core/components/ui/loader/loader.js +11 -3
  51. package/core/components/ui/loader/styles/inline.js +14 -16
  52. package/core/components/ui/menu/menu-item.js +2 -1
  53. package/core/components/ui/menu/menu.js +6 -22
  54. package/core/components/ui/modal/modal-close.js +2 -1
  55. package/core/components/ui/modal/modal.d.ts +13 -1
  56. package/core/components/ui/modal/modal.js +70 -10
  57. package/core/components/ui/pop/pop.d.ts +9 -3
  58. package/core/components/ui/pop/pop.js +46 -23
  59. package/core/components/ui/table/table-tr.d.ts +10 -2
  60. package/core/components/ui/table/table-tr.js +30 -2
  61. package/core/components/ui/table/table.d.ts +1 -0
  62. package/core/components/ui/table/table.js +7 -1
  63. package/core/components/ui/theme/theme-collection/core-variables.js +8 -19
  64. package/core/components/ui/theme/theme.d.ts +6 -0
  65. package/core/components/ui/theme/theme.js +11 -13
  66. package/core/components/ui/toast/message-subscriber.d.ts +0 -8
  67. package/core/components/ui/toast/message-subscriber.js +0 -46
  68. package/core/components/ui/toast/toast-item.js +31 -40
  69. package/core/components/ui/toast/toast.d.ts +5 -1
  70. package/core/components/ui/toast/toast.js +80 -13
  71. package/core/components/ui/tooltip/tooltip.d.ts +3 -1
  72. package/core/components/ui/tooltip/tooltip.js +22 -0
  73. package/core/core.d.ts +1 -0
  74. package/core/core.js +1 -0
  75. package/core/decorators/Subscriber.d.ts +3 -3
  76. package/core/decorators/Subscriber.js +66 -23
  77. package/core/directives/DataProvider.d.ts +12 -7
  78. package/core/directives/DataProvider.js +23 -8
  79. package/core/directives/Wording.d.ts +42 -0
  80. package/core/directives/Wording.js +202 -0
  81. package/core/mixins/Fetcher.d.ts +8 -11
  82. package/core/mixins/Fetcher.js +38 -22
  83. package/core/mixins/FormCheckable.d.ts +1 -4
  84. package/core/mixins/FormElement.d.ts +1 -0
  85. package/core/mixins/FormElement.js +3 -6
  86. package/core/mixins/FormInput.d.ts +3 -5
  87. package/core/mixins/FormInput.js +4 -0
  88. package/core/mixins/Subscriber.d.ts +0 -4
  89. package/core/mixins/Subscriber.js +13 -89
  90. package/core/mixins/TemplatesContainer.js +9 -0
  91. package/core/utils/Format.d.ts +1 -0
  92. package/core/utils/Format.js +16 -0
  93. package/core/utils/HTML.d.ts +13 -0
  94. package/core/utils/HTML.js +42 -3
  95. package/core/utils/Objects.d.ts +1 -0
  96. package/core/utils/Objects.js +5 -0
  97. package/core/utils/PublisherProxy.d.ts +16 -10
  98. package/core/utils/PublisherProxy.js +112 -74
  99. package/core/utils/Utils.d.ts +1 -0
  100. package/core/utils/Utils.js +5 -0
  101. package/core/utils/api.d.ts +26 -0
  102. package/core/utils/api.js +135 -3
  103. package/core/utils/url-pattern.d.ts +2 -0
  104. package/core/utils/url-pattern.js +2 -0
  105. package/mixins.d.ts +6 -16
  106. package/package.json +9 -2
@@ -1,7 +1,12 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any*/
1
+ import HTML from "./HTML";
2
2
  function isComplex(value) {
3
3
  return typeof value === "object" && value != null;
4
4
  }
5
+ const queueTaskPromise = async () => {
6
+ return new Promise((resolve) => {
7
+ window.queueMicrotask(() => resolve(null));
8
+ });
9
+ };
5
10
  /**
6
11
  * Custom Proxy contient les méthodes des publishers retournés par PublisherManager.get(publisherId) qui seront utilisées couramment
7
12
  */
@@ -16,6 +21,7 @@ export class PublisherProxy {
16
21
  this._templateFillListeners_ = new Set();
17
22
  this._lockInternalMutationPublishing_ = false;
18
23
  this._instanceCounter_ = 0;
24
+ this._assignmentId_ = 0;
19
25
  this._value_ = target;
20
26
  this.parent = parentProxPub || null;
21
27
  this.root = this;
@@ -52,20 +58,26 @@ export class PublisherProxy {
52
58
  }
53
59
  _publishInternalMutation_(lockInternalMutationsTransmission = false) {
54
60
  this._mutationListeners_.forEach((handler) => handler());
55
- if (lockInternalMutationsTransmission)
56
- return;
57
- if (!PublisherManager.changed && this._is_savable_) {
61
+ if (this._is_savable_ && !PublisherManager.changed) {
58
62
  PublisherManager.changed = true;
59
63
  PublisherManager.saveId++;
60
64
  const saveId = PublisherManager.saveId;
61
65
  setTimeout(() => PublisherManager.getInstance().saveToLocalStorage(saveId), 1000);
62
66
  }
67
+ if (lockInternalMutationsTransmission)
68
+ return;
63
69
  if (this.parent) {
64
70
  this.parent._publishInternalMutation_();
65
71
  }
66
72
  }
67
- _publishAssignement_(lockInternalMutationsTransmission = false) {
68
- this._assignListeners_.forEach((handler) => handler(this.get()));
73
+ async _publishAssignement_(lockInternalMutationsTransmission = false) {
74
+ this._assignmentId_++;
75
+ const currentId = this._assignmentId_;
76
+ await queueTaskPromise();
77
+ if (currentId !== this._assignmentId_)
78
+ return;
79
+ const newValue = this.get();
80
+ this._assignListeners_.forEach((handler) => handler(newValue));
69
81
  this._publishInternalMutation_(lockInternalMutationsTransmission);
70
82
  }
71
83
  _publishInvalidation_() {
@@ -98,6 +110,8 @@ export class PublisherProxy {
98
110
  onAssign(handler, directHandlerCall = true) {
99
111
  if (typeof handler != "function")
100
112
  return;
113
+ if (this._assignListeners_.has(handler))
114
+ return;
101
115
  this._assignListeners_.add(handler);
102
116
  if (directHandlerCall)
103
117
  handler(this.get());
@@ -194,7 +208,7 @@ export class PublisherProxy {
194
208
  /**
195
209
  * Assigne une nouvelle valeur au proxy ce qui déclenche la transmission de la donnée en fonction des "écouteurs" associés
196
210
  */
197
- set(newValue, lockInternalMutationsTransmission = false) {
211
+ async set(newValue, lockInternalMutationsTransmission = false) {
198
212
  /**
199
213
  * On retounre tout de suite si la valeur n'a pas changé
200
214
  */
@@ -211,13 +225,14 @@ export class PublisherProxy {
211
225
  */
212
226
  const prevValue = this._value_;
213
227
  this._value_ = isComplex(newValue) ? newValue : { __value: newValue };
228
+ this._cachedGet_ = undefined;
214
229
  /**
215
230
  * Si il s'agit d'une valeur primitive (un entier, une chaine ) la valeure en renseignée par un objet contenant la vaeur {__value}
216
231
  * On publie juste et on sen va.
217
232
  */
218
233
  const isPrimitiveValue = Object.prototype.hasOwnProperty.call(this._value_, "__value");
219
234
  if (isPrimitiveValue) {
220
- this._publishAssignement_(lockInternalMutationsTransmission);
235
+ await this._publishAssignement_(lockInternalMutationsTransmission);
221
236
  return true;
222
237
  }
223
238
  /**
@@ -227,30 +242,28 @@ export class PublisherProxy {
227
242
  * On publie les maj au fur et a mesure de modifications
228
243
  */
229
244
  for (const key in this._value_) {
230
- if (typeof this._value_[key] === "undefined")
245
+ if (this._value_[key] === undefined)
231
246
  delete this._value_[key];
232
247
  }
233
- Array.from(this._proxies_.keys()).forEach((key) => {
248
+ this._proxies_.forEach((_subProxy, key) => {
234
249
  /**
235
250
  * On supprime les proxys qui ne sont plus dans la nouvelle valeur si ils n'on pas d'écouteurs
236
251
  **/
237
- if (typeof this._value_[key] === "undefined" && this._proxies_.has(key)) {
238
- const subProxy = this._proxies_.get(key);
239
- if (!subProxy?.hasListener()) {
240
- this._proxies_.delete(key);
241
- }
242
- else {
243
- if (key != "_parent_") {
244
- if (prevValue[key])
245
- this._value_[key] = null;
246
- }
252
+ if (this._value_[key] === undefined) {
253
+ // if (!_subProxy?.hasListener()) {
254
+ // // this._proxies_.delete(key);
255
+ // } else {
256
+ if (key != "_parent_") {
257
+ if (prevValue[key])
258
+ this._value_[key] = null;
247
259
  }
260
+ // }
248
261
  }
249
262
  });
250
263
  /**
251
264
  * On prévient les écouteurs que la valeur a changé
252
265
  */
253
- this._publishAssignement_();
266
+ await this._publishAssignement_();
254
267
  /**
255
268
  * Si la donnée est complexe (objet, tableau)
256
269
  * on crée les proxys pour les sous-éléments qui n'en on pas
@@ -262,27 +275,29 @@ export class PublisherProxy {
262
275
  const isVComplex = isComplex(v);
263
276
  const valueV = isVComplex ? v : { __value: v };
264
277
  if (!this._proxies_.has(key)) {
265
- const newPublisher = new Publisher({}, this);
266
- this._proxies_.set(key, newPublisher);
267
- newPublisher._proxies_.set("_parent_", this);
278
+ // A surveiller ancienne version
279
+ // const newPublisher = new Publisher({}, this);
280
+ // this._proxies_.set(key, newPublisher);
281
+ // newPublisher._proxies_.set("_parent_", this);
282
+ this._publishDynamicFilling_(key, v);
283
+ continue;
268
284
  }
269
- this._proxies_.get(key)?.set(valueV, true);
285
+ await this._proxies_.get(key)?.set(valueV, true);
270
286
  this._publishDynamicFilling_(key, v);
271
287
  }
272
288
  }
273
289
  return true;
274
290
  }
275
- /**
276
- * Extraire la valeur actuelle du proxy
277
- */
278
291
  get() {
292
+ if (this._cachedGet_ !== undefined)
293
+ return this._cachedGet_;
279
294
  if (PublisherManager.modifiedCollectore.length > 0)
280
295
  PublisherManager.modifiedCollectore[0].add(this);
281
296
  if (Object.prototype.hasOwnProperty.call(this._value_, "__value")) {
282
297
  const v = this._value_.__value;
283
- return (v != undefined ? v : null);
298
+ return (this._cachedGet_ = (v != undefined ? v : null));
284
299
  }
285
- return this._value_;
300
+ return (this._cachedGet_ = this._value_);
286
301
  }
287
302
  /**
288
303
  * retourner le webcomponent auquel le proxy est associé
@@ -299,11 +314,9 @@ export class PublisherProxy {
299
314
  }
300
315
  PublisherProxy.instances = new Map();
301
316
  PublisherProxy.instancesCounter = 0;
302
- /**
303
- * Utilitaires de gestion des Publisher
304
- * Obtenir, replacer ou supprimer un Publisher
305
- *
306
- */
317
+ if (typeof __BUILD_DATE__ === "undefined") {
318
+ window.__BUILD_DATE__ = "No build date";
319
+ }
307
320
  export class PublisherManager {
308
321
  constructor() {
309
322
  this.enabledLocaStorageProxies = [];
@@ -383,6 +396,8 @@ export class PublisherManager {
383
396
  * shortcut static pour supprimer un publisher de la liste et appel également delete sur le publisher ce qui le supprime, de même que ses sous publishers
384
397
  */
385
398
  static delete(id) {
399
+ if (!id)
400
+ return false;
386
401
  return PublisherManager.getInstance().delete(id);
387
402
  }
388
403
  /**
@@ -391,7 +406,7 @@ export class PublisherManager {
391
406
  */
392
407
  async setLocalData(publisher, id) {
393
408
  await this.isLocalStrorageReady;
394
- publisher.set(this.localStorageData[id + "¤page:>" + document.location.pathname]?.data || publisher.get());
409
+ publisher.set(this.localStorageData[id + "¤lang_" + HTML.getLanguage()]?.data || publisher.get());
395
410
  }
396
411
  get(id, options) {
397
412
  const hasLocalStorage = options?.localStorageMode === "enabled";
@@ -416,7 +431,15 @@ export class PublisherManager {
416
431
  this.publishers.set(id, publisher);
417
432
  }
418
433
  /**
419
- * supprimer un publisher de la liste et appel également delete sur le publisher ce qui le supprime, de même que ses sous publishers
434
+ * @warning
435
+ * !!!!! ATTENTION !!!!!
436
+ * Il est fort à aprier que vous ne voulez pas utiliser cette methode
437
+ * Il s'agit d'une supression complete
438
+ * * du publisher de la liste
439
+ * * des bindings
440
+ * * de même que ses sous publishers
441
+ *
442
+ * UTILISEZ PLUTÔT la méthode publisher.set({}) pour réinitialiser un publisher sans perdre les ecouteurs
420
443
  */
421
444
  delete(id) {
422
445
  if (!this.publishers.has(id))
@@ -445,7 +468,7 @@ export class PublisherManager {
445
468
  const data = publisher?.get();
446
469
  if (!data)
447
470
  continue;
448
- this.localStorageData[key + "¤page:>" + document.location.pathname] = {
471
+ this.localStorageData[key + "¤lang_" + HTML.getLanguage()] = {
449
472
  lastModifiationMS: new Date().getTime(),
450
473
  data: data,
451
474
  };
@@ -495,11 +518,48 @@ export class PublisherManager {
495
518
  return new TextDecoder().decode(result);
496
519
  }
497
520
  }
521
+ PublisherManager.buildDate = __BUILD_DATE__;
498
522
  PublisherManager.changed = false;
499
523
  PublisherManager.saving = false;
500
524
  PublisherManager.saveId = 0;
501
525
  PublisherManager.instance = null;
502
526
  PublisherManager.modifiedCollectore = [];
527
+ const internalProps = new Set([
528
+ "invalidate",
529
+ "onInvalidate",
530
+ "offInvalidate",
531
+ "onAssign",
532
+ "offAssign",
533
+ "startDynamicFilling",
534
+ "stopDynamicFilling",
535
+ "startTemplateFilling",
536
+ "stopTemplateFilling",
537
+ "onInternalMutation",
538
+ "offInternalMutation",
539
+ "set",
540
+ "get",
541
+ "$tag",
542
+ "_cachedGet_",
543
+ "_templateFillListeners_",
544
+ "_fillListeners_",
545
+ "_assignListeners_",
546
+ "_invalidateListeners_",
547
+ "_publishInternalMutation_",
548
+ "hasListener",
549
+ "delete",
550
+ "_mutationListeners_",
551
+ "_publishDynamicFilling_",
552
+ "_publishInvalidation_",
553
+ "_publishTemplateFilling_",
554
+ "_publishAssignement_",
555
+ "_proxies_",
556
+ "parent",
557
+ "_value_",
558
+ "_is_savable_",
559
+ "_lockInternalMutationPublishing_",
560
+ "_instanceCounter_",
561
+ "_assignmentId_",
562
+ ]);
503
563
  /**
504
564
  * Le Proxy Javascript
505
565
  */
@@ -516,40 +576,7 @@ export default class Publisher extends PublisherProxy {
516
576
  if (sKey == Symbol.toPrimitive) {
517
577
  return () => thisProxy.get();
518
578
  }
519
- if ([
520
- "invalidate",
521
- "onInvalidate",
522
- "offInvalidate",
523
- "onAssign",
524
- "offAssign",
525
- "startDynamicFilling",
526
- "stopDynamicFilling",
527
- "startTemplateFilling",
528
- "stopTemplateFilling",
529
- "onInternalMutation",
530
- "offInternalMutation",
531
- "set",
532
- "get",
533
- "$tag",
534
- "_templateFillListeners_",
535
- "_fillListeners_",
536
- "_assignListeners_",
537
- "_invalidateListeners_",
538
- "_publishInternalMutation_",
539
- "hasListener",
540
- "delete",
541
- "_mutationListeners_",
542
- "_publishDynamicFilling_",
543
- "_publishInvalidation_",
544
- "_publishTemplateFilling_",
545
- "_publishAssignement_",
546
- "_proxies_",
547
- "parent",
548
- "_value_",
549
- "_is_savable_",
550
- "_lockInternalMutationPublishing_",
551
- "_instanceCounter_",
552
- ].includes(sKey))
579
+ if (internalProps.has(sKey))
553
580
  return publisherInstance[sKey];
554
581
  if (!publisherInstance._proxies_.has(sKey)) {
555
582
  const vValue = publisherInstance._value_[sKey];
@@ -569,6 +596,14 @@ export default class Publisher extends PublisherProxy {
569
596
  publisherInstance._value_ = vValue;
570
597
  return true;
571
598
  }
599
+ if (sKey == "_cachedGet_") {
600
+ publisherInstance._cachedGet_ = vValue;
601
+ return true;
602
+ }
603
+ if (sKey == "_assignmentId_") {
604
+ publisherInstance._assignmentId_ = vValue;
605
+ return true;
606
+ }
572
607
  if (sKey == "_is_savable_") {
573
608
  publisherInstance._is_savable_ = vValue;
574
609
  return true;
@@ -599,9 +634,12 @@ export default class Publisher extends PublisherProxy {
599
634
  */
600
635
  deleteProperty: function (publisherInstance, sKey) {
601
636
  publisherInstance;
602
- // publisherInstance._proxies_.get(sKey).set(null);
603
637
  publisherInstance._publishDynamicFilling_(sKey, null);
604
- publisherInstance._proxies_.delete(sKey);
638
+ // if (!publisherInstance._proxies_.get(sKey)?.hasListener()) {
639
+ // publisherInstance._proxies_.delete(sKey);
640
+ // } else {
641
+ publisherInstance._proxies_.get(sKey)?.set(null);
642
+ // }
605
643
  return delete publisherInstance._value_[sKey];
606
644
  },
607
645
  // enumerate: function (publisherInstance, sKey): CoreJSType {
@@ -1,3 +1,4 @@
1
1
  export default class Utils {
2
+ static queueTaskPromise(): Promise<unknown>;
2
3
  static delayPromise(timeoutMs: number): Promise<unknown>;
3
4
  }
@@ -1,4 +1,9 @@
1
1
  export default class Utils {
2
+ static async queueTaskPromise() {
3
+ return new Promise((resolve) => {
4
+ window.queueMicrotask(() => resolve(null));
5
+ });
6
+ }
2
7
  static async delayPromise(timeoutMs) {
3
8
  return new Promise((resolve) => {
4
9
  setTimeout(resolve, timeoutMs);
@@ -1,6 +1,8 @@
1
1
  import { CoreJSType } from "@supersoniks/concorde/core/_types/types";
2
2
  export type APIConfiguration = {
3
3
  serviceURL: string | null;
4
+ /** un flag pour indiquer de bloquer les appels suivant au même serviceurl tant que celuis-ci n'a pas terminé */
5
+ blockUntilDone?: boolean;
4
6
  token: string | null;
5
7
  userName: string | null;
6
8
  password: string | null;
@@ -10,6 +12,7 @@ export type APIConfiguration = {
10
12
  credentials?: RequestCredentials;
11
13
  cache?: RequestCache;
12
14
  };
15
+ export type CallState = "loading" | "done" | "error" | undefined;
13
16
  export type ResultTypeInterface = CoreJSType & {
14
17
  _sonic_http_response_?: Response;
15
18
  text?: string;
@@ -70,18 +73,37 @@ declare class API {
70
73
  * Tableau static des tentatives échouées de récupération auto du token
71
74
  */
72
75
  static failledTokenUpdates: Map<string | null, true>;
76
+ /**
77
+ * Tableau static des flags pour savoir si le premier appel a été fait pour chaque serviceURL
78
+ */
79
+ static firstCallDoneFlags: Map<string | null, CallState>;
73
80
  /**
74
81
  * Le endPoint pour obtenir le bearer token qui sera concaténé à l'url du service
75
82
  */
76
83
  addHTTPResponse: boolean;
77
84
  cache: RequestCache;
78
85
  lastResult?: Response;
86
+ isServiceSimulated: boolean;
87
+ blockUntilDone: boolean;
79
88
  constructor(config: APIConfiguration);
80
89
  handleResult(fetchResult: Response, lastCall: APICall): Promise<ResultTypeInterface>;
81
90
  /**
82
91
  * Basic auth
83
92
  */
84
93
  auth(): Promise<void>;
94
+ /**
95
+ * avec localget, on ne passe pas par le système de token
96
+ * on recupère path sans les searchparams nommée pathWithoutSearchParams
97
+ * on cherche dans PublisherManager.get(pathWithoutSearchParams).get() les données qui matchent les searchparams présents dans path
98
+ * on retourne les données selon le même format que le retour de get
99
+ *
100
+ * @todo netttoyer
101
+ */
102
+ localGet<T>(dataProvider: string, searchString: string): Promise<T & ResultTypeInterface>;
103
+ /**
104
+ * firstCallDone is a function that returns a promise that is resolved when the first call to the API is done for each serviceURL whatever api instance is used
105
+ */
106
+ firstCallDone(): Promise<unknown>;
85
107
  get<T>(path: string, additionalHeaders?: HeadersInit): Promise<T & ResultTypeInterface>;
86
108
  /**
87
109
  * Création du header, avec authentification si besoin
@@ -105,6 +127,10 @@ declare class API {
105
127
  * Appel send en utilisant le méthode POST
106
128
  */
107
129
  post<T, SendType = CoreJSType>(path: string, data: SendType, additionalHeaders?: HeadersInit): Promise<T & ResultTypeInterface>;
130
+ /**
131
+ * Appel send en utilisant le méthode PATCH
132
+ */
133
+ patch<T, SendType = CoreJSType>(path: string, data: SendType, additionalHeaders?: HeadersInit): Promise<T & ResultTypeInterface>;
108
134
  /**
109
135
  * Appel send en utilisant le méthode delete
110
136
  */
package/core/utils/api.js CHANGED
@@ -2,6 +2,7 @@
2
2
  /* eslint no-async-promise-executor: 0 */ // --> OFF
3
3
  import HTML from "@supersoniks/concorde/core/utils/HTML";
4
4
  import Objects from "@supersoniks/concorde/core/utils/Objects";
5
+ import { PublisherManager } from "./PublisherProxy";
5
6
  class API {
6
7
  set token(token) {
7
8
  this._token = token;
@@ -31,7 +32,13 @@ class API {
31
32
  */
32
33
  this.addHTTPResponse = false;
33
34
  this.cache = "default";
35
+ this.isServiceSimulated = false;
36
+ this.blockUntilDone = false;
34
37
  this.serviceURL = config.serviceURL;
38
+ this.blockUntilDone = config.blockUntilDone || false;
39
+ if (this.serviceURL == "publisher://") {
40
+ this.isServiceSimulated = true;
41
+ }
35
42
  if (!this.serviceURL)
36
43
  this.serviceURL = document.location.origin;
37
44
  this.userName = config.userName;
@@ -45,6 +52,7 @@ class API {
45
52
  this.cache = config.cache || "default";
46
53
  }
47
54
  async handleResult(fetchResult, lastCall) {
55
+ API.firstCallDoneFlags.set(this.serviceURL, "done");
48
56
  this.lastResult = fetchResult;
49
57
  const contentType = fetchResult.headers.get("content-type")?.toLowerCase();
50
58
  const httpCode = fetchResult.status;
@@ -118,7 +126,116 @@ class API {
118
126
  API.failledTokenUpdates.set(this.serviceURL, true);
119
127
  }
120
128
  }
129
+ /**
130
+ * avec localget, on ne passe pas par le système de token
131
+ * on recupère path sans les searchparams nommée pathWithoutSearchParams
132
+ * on cherche dans PublisherManager.get(pathWithoutSearchParams).get() les données qui matchent les searchparams présents dans path
133
+ * on retourne les données selon le même format que le retour de get
134
+ *
135
+ * @todo netttoyer
136
+ */
137
+ async localGet(dataProvider, searchString) {
138
+ const publisher = PublisherManager.get(dataProvider);
139
+ console.log(publisher);
140
+ const searchParams = new URLSearchParams(searchString.split("?")[1] || "");
141
+ const dataObject = publisher.get();
142
+ let data = [];
143
+ if (!Array.isArray(dataObject)) {
144
+ data = [dataObject];
145
+ }
146
+ else {
147
+ data = dataObject;
148
+ }
149
+ const result = [];
150
+ let limit = Number.POSITIVE_INFINITY;
151
+ let offset = 0;
152
+ let limitOffsetparams = 0;
153
+ if (searchParams.has("limit")) {
154
+ limit = parseInt(searchParams.get("limit") || "0");
155
+ limitOffsetparams++;
156
+ }
157
+ if (searchParams.has("offset")) {
158
+ offset = parseInt(searchParams.get("offset") || "0");
159
+ limitOffsetparams++;
160
+ }
161
+ if (limitOffsetparams > 0) {
162
+ searchParams.delete("limit");
163
+ searchParams.delete("offset");
164
+ }
165
+ if (searchParams.size === 0)
166
+ return data.slice(offset, offset + limit);
167
+ for (const [key, value] of searchParams.entries()) {
168
+ const values = value.split(",").map((s) => s.trim());
169
+ for (const v of values) {
170
+ for (const item of data) {
171
+ //si l'item est une valeur primitive on regarde si vaue correspond à item simplement
172
+ if (typeof item !== "object") {
173
+ if (!isNaN(+value)) {
174
+ if (item == value) {
175
+ result.push(item);
176
+ }
177
+ }
178
+ else if (item.toString().includes(value)) {
179
+ result.push(item);
180
+ }
181
+ }
182
+ else {
183
+ const record = item;
184
+ //si l'item est un objet
185
+ //faire un comparaison de la version string de la même clef dans item pour voir si elle contient value
186
+ if (!record[key])
187
+ continue;
188
+ //si la valeur est un nombre, on compare les valeurs directement
189
+ if (!isNaN(+v)) {
190
+ if (record[key] == v) {
191
+ result.push(item);
192
+ }
193
+ }
194
+ else {
195
+ if (record[key]?.toString().toLowerCase().includes(v.toLowerCase())) {
196
+ result.push(item);
197
+ }
198
+ }
199
+ }
200
+ }
201
+ }
202
+ }
203
+ return result.slice(offset, offset + limit);
204
+ }
205
+ /**
206
+ * firstCallDone is a function that returns a promise that is resolved when the first call to the API is done for each serviceURL whatever api instance is used
207
+ */
208
+ firstCallDone() {
209
+ return new Promise((resolve) => {
210
+ if (!API.firstCallDoneFlags.has(this.serviceURL)) {
211
+ API.firstCallDoneFlags.set(this.serviceURL, "loading");
212
+ resolve(true);
213
+ }
214
+ else {
215
+ const loop = () => {
216
+ if (![undefined, "loading"].includes(API.firstCallDoneFlags.get(this.serviceURL))) {
217
+ resolve(true);
218
+ }
219
+ else {
220
+ window.requestAnimationFrame(loop);
221
+ }
222
+ };
223
+ loop();
224
+ }
225
+ });
226
+ }
121
227
  async get(path, additionalHeaders) {
228
+ await this.firstCallDone();
229
+ if (this.blockUntilDone) {
230
+ API.firstCallDoneFlags.set(this.serviceURL, "loading");
231
+ }
232
+ const regExp = /dataProvider\((.*?)\)(.*?)$/;
233
+ if (regExp.test(path)) {
234
+ const match = path.match(regExp);
235
+ if (!match)
236
+ throw new Error("dataProvider path is not valid");
237
+ return await this.localGet(match[1], match[2]);
238
+ }
122
239
  const lastCall = {
123
240
  apiMethod: "get",
124
241
  path: path,
@@ -132,9 +249,14 @@ class API {
132
249
  });
133
250
  if (!API.loadingGetPromises.has(mapKey)) {
134
251
  const promise = new Promise(async (resolve) => {
135
- const result = await fetch(url, { headers: headers, credentials: this.credentials, cache: this.cache });
136
- const handledResult = await this.handleResult(result, lastCall);
137
- resolve(handledResult);
252
+ try {
253
+ const result = await fetch(url, { headers: headers, credentials: this.credentials, cache: this.cache });
254
+ const handledResult = await this.handleResult(result, lastCall);
255
+ resolve(handledResult);
256
+ }
257
+ catch (e) {
258
+ resolve(null);
259
+ }
138
260
  });
139
261
  API.loadingGetPromises.set(mapKey, promise);
140
262
  }
@@ -233,6 +355,12 @@ class API {
233
355
  async post(path, data, additionalHeaders) {
234
356
  return this.send(path, data, "POST", additionalHeaders);
235
357
  }
358
+ /**
359
+ * Appel send en utilisant le méthode PATCH
360
+ */
361
+ async patch(path, data, additionalHeaders) {
362
+ return this.send(path, data, "PATCH", additionalHeaders);
363
+ }
236
364
  /**
237
365
  * Appel send en utilisant le méthode delete
238
366
  */
@@ -256,4 +384,8 @@ API.invalidTokens = [];
256
384
  * Tableau static des tentatives échouées de récupération auto du token
257
385
  */
258
386
  API.failledTokenUpdates = new Map();
387
+ /**
388
+ * Tableau static des flags pour savoir si le premier appel a été fait pour chaque serviceURL
389
+ */
390
+ API.firstCallDoneFlags = new Map();
259
391
  export default API;
@@ -0,0 +1,2 @@
1
+ import UrlPattern from "url-pattern";
2
+ export default UrlPattern;
@@ -0,0 +1,2 @@
1
+ import UrlPattern from "url-pattern";
2
+ export default UrlPattern;