@communecter/cocolight-api-client 1.0.30 → 1.0.32

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.
@@ -34,6 +34,8 @@ export class BaseEntity {
34
34
  /** @type {boolean} Indique si le draft est synchronisé avec le serveur */
35
35
  _syncReactiveDraft = false;
36
36
 
37
+ static entityTag = "BaseEntity";
38
+
37
39
  /**
38
40
  * Constructeur de l'entité.
39
41
  * @param {Object} parent - L'ApiClient ou une entité parente.
@@ -54,7 +56,7 @@ export class BaseEntity {
54
56
  * @throws {ApiError} Si les dépendances ou parent sont invalides.
55
57
  */
56
58
  constructor(parent, data = {}, deps = {}, config = {}) {
57
- this.__entityTag = config.entityTag || this.getEntityTag(this.constructor.name) || "BaseEntity";
59
+ this.__entityTag = config.entityTag || this.getEntityTag(this.constructor.entityTag) || "BaseEntity";
58
60
  this.deps = deps;
59
61
 
60
62
  if (this.getEntityTag(parent?.__entityTag) === "ApiClient") {
@@ -1680,33 +1682,63 @@ export class BaseEntity {
1680
1682
  * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1681
1683
  * @returns {Promise<Object>} - Les données de réponse.
1682
1684
  */
1683
- async getOrganizations(data = {}, isNext = false) {
1685
+ async getOrganizations(data = {}) {
1684
1686
  data.searchType = this._getDefaultFromEndpoint("GET_ORGANIZATIONS_NO_ADMIN", "searchType");
1685
1687
  // data.searchBy = "ALL";
1686
- return this._paginateWith(data, isNext, async (finalData) => {
1687
- if(this.isMe){
1688
- finalData.pathParams = { type: this.getEntityType(), id: this.id };
1688
+ // return this._paginateWith(data, isNext, async (finalData) => {
1689
+ // if(this.isMe){
1690
+ // finalData.pathParams = { type: this.getEntityType(), id: this.id };
1691
+ // // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1692
+ // // finalData.filters = {
1693
+ // // [`links.members.${this.id}`]: { "$exists": true },
1694
+ // // [`links.members.${this.id}.toBeValidated`]: { "$exists": false },
1695
+ // // [`links.members.${this.id}.isInviting`]: { "$exists": false }
1696
+ // // };
1697
+ // } else {
1698
+ // delete finalData?.pathParams;
1699
+ // finalData.filters = {
1700
+ // [`links.members.${this.id}`]: { "$exists": true },
1701
+ // [`links.members.${this.id}.toBeValidated`]: { "$exists": false },
1702
+ // [`links.members.${this.id}.isInviting`]: { "$exists": false }
1703
+ // };
1704
+ // }
1705
+
1706
+ // const fetchFn = this.isMe
1707
+ // ? () => this.callIsMe(() => this.endpointApi.getOrganizationsAdmin(finalData))
1708
+ // : () => this.endpointApi.getOrganizationsNoAdmin(finalData);
1709
+
1710
+ // return fetchFn();
1711
+ // });
1712
+
1713
+ const paginator = this._createPaginatorEngine({
1714
+ initialData: data,
1715
+ finalizer: async (finalData) => {
1716
+ if(this.isMe){
1717
+ finalData.pathParams = { type: this.getEntityType(), id: this.id };
1689
1718
  // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1690
1719
  // finalData.filters = {
1691
1720
  // [`links.members.${this.id}`]: { "$exists": true },
1692
1721
  // [`links.members.${this.id}.toBeValidated`]: { "$exists": false },
1693
1722
  // [`links.members.${this.id}.isInviting`]: { "$exists": false }
1694
1723
  // };
1695
- } else {
1696
- delete finalData?.pathParams;
1697
- finalData.filters = {
1698
- [`links.members.${this.id}`]: { "$exists": true },
1699
- [`links.members.${this.id}.toBeValidated`]: { "$exists": false },
1700
- [`links.members.${this.id}.isInviting`]: { "$exists": false }
1701
- };
1702
- }
1724
+ } else {
1725
+ delete finalData?.pathParams;
1726
+ finalData.filters = {
1727
+ [`links.members.${this.id}`]: { "$exists": true },
1728
+ [`links.members.${this.id}.toBeValidated`]: { "$exists": false },
1729
+ [`links.members.${this.id}.isInviting`]: { "$exists": false }
1730
+ };
1731
+ }
1703
1732
 
1704
- const fetchFn = this.isMe
1705
- ? () => this.callIsMe(() => this.endpointApi.getOrganizationsAdmin(finalData))
1706
- : () => this.endpointApi.getOrganizationsNoAdmin(finalData);
1733
+ const fetchFn = this.isMe
1734
+ ? () => this.callIsMe(() => this.endpointApi.getOrganizationsAdmin(finalData))
1735
+ : () => this.endpointApi.getOrganizationsNoAdmin(finalData);
1707
1736
 
1708
- return fetchFn();
1737
+ return fetchFn();
1738
+ }
1709
1739
  });
1740
+
1741
+ return paginator.next();
1710
1742
  }
1711
1743
 
1712
1744
  /**
@@ -1716,37 +1748,70 @@ export class BaseEntity {
1716
1748
  * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1717
1749
  * @returns {Promise<Object>} - Les données de réponse.
1718
1750
  */
1719
- async getProjects(data = {}, isNext = false) {
1751
+ async getProjects(data = {}) {
1720
1752
  data.searchType = this._getDefaultFromEndpoint("GET_PROJECTS_ADMIN", "searchType");
1721
1753
  // data.searchBy = "ALL";
1722
- return this._paginateWith(data, isNext, async (finalData) => {
1723
- if(this.isMe){
1724
- finalData.pathParams = { type: this.getEntityType(), id: this.id };
1725
- // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1726
- // finalData.filters = {
1727
- // "$or": {
1728
- // [`links.contributors.${this.id}`]: { "$exists": true },
1729
- // [`parent.${this.id}`]: { "$exists": true }
1730
- // },
1731
- // [`links.contributors.${this.id}`]: { "$exists": true }
1732
- // };
1733
- } else {
1734
- delete finalData?.pathParams;
1735
- finalData.filters = {
1736
- "$or": {
1737
- [`links.contributors.${this.id}`]: { "$exists": true },
1738
- [`parent.${this.id}`]: { "$exists": true }
1739
- },
1740
- [`links.contributors.${this.id}`]: { "$exists": true }
1741
- };
1742
- }
1754
+ // return this._paginateWith(data, isNext, async (finalData) => {
1755
+ // if(this.isMe){
1756
+ // finalData.pathParams = { type: this.getEntityType(), id: this.id };
1757
+ // // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1758
+ // // finalData.filters = {
1759
+ // // "$or": {
1760
+ // // [`links.contributors.${this.id}`]: { "$exists": true },
1761
+ // // [`parent.${this.id}`]: { "$exists": true }
1762
+ // // },
1763
+ // // [`links.contributors.${this.id}`]: { "$exists": true }
1764
+ // // };
1765
+ // } else {
1766
+ // delete finalData?.pathParams;
1767
+ // finalData.filters = {
1768
+ // "$or": {
1769
+ // [`links.contributors.${this.id}`]: { "$exists": true },
1770
+ // [`parent.${this.id}`]: { "$exists": true }
1771
+ // },
1772
+ // [`links.contributors.${this.id}`]: { "$exists": true }
1773
+ // };
1774
+ // }
1775
+
1776
+ // const fetchFn = this.isMe
1777
+ // ? () => this.callIsMe(() => this.endpointApi.getProjectsAdmin(finalData))
1778
+ // : () => this.endpointApi.getProjectsNoAdmin(finalData);
1779
+
1780
+ // return fetchFn();
1781
+ // });
1782
+ const paginator = this._createPaginatorEngine({
1783
+ initialData: data,
1784
+ finalizer: async (finalData) => {
1785
+ if(this.isMe){
1786
+ finalData.pathParams = { type: this.getEntityType(), id: this.id };
1787
+ // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1788
+ // finalData.filters = {
1789
+ // "$or": {
1790
+ // [`links.contributors.${this.id}`]: { "$exists": true },
1791
+ // [`parent.${this.id}`]: { "$exists": true }
1792
+ // },
1793
+ // [`links.contributors.${this.id}`]: { "$exists": true }
1794
+ // };
1795
+ } else {
1796
+ delete finalData?.pathParams;
1797
+ finalData.filters = {
1798
+ "$or": {
1799
+ [`links.contributors.${this.id}`]: { "$exists": true },
1800
+ [`parent.${this.id}`]: { "$exists": true }
1801
+ },
1802
+ [`links.contributors.${this.id}`]: { "$exists": true }
1803
+ };
1804
+ }
1743
1805
 
1744
- const fetchFn = this.isMe
1745
- ? () => this.callIsMe(() => this.endpointApi.getProjectsAdmin(finalData))
1746
- : () => this.endpointApi.getProjectsNoAdmin(finalData);
1806
+ const fetchFn = this.isMe
1807
+ ? () => this.callIsMe(() => this.endpointApi.getProjectsAdmin(finalData))
1808
+ : () => this.endpointApi.getProjectsNoAdmin(finalData);
1747
1809
 
1748
- return fetchFn();
1810
+ return fetchFn();
1811
+ }
1749
1812
  });
1813
+
1814
+ return paginator.next();
1750
1815
  }
1751
1816
 
1752
1817
  /**
@@ -1756,29 +1821,55 @@ export class BaseEntity {
1756
1821
  * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1757
1822
  * @returns {Promise<Object>} - Les données de réponse.
1758
1823
  */
1759
- async getPois(data = {}, isNext = false) {
1824
+ async getPois(data = {}) {
1760
1825
  data.searchType = this._getDefaultFromEndpoint("GET_POIS_ADMIN", "searchType");
1761
1826
  // data.searchBy = "ALL";
1762
- return this._paginateWith(data, isNext, async (finalData) => {
1763
- if(this.isMe){
1764
- finalData.pathParams = { type: this.getEntityType(), id: this.id };
1765
- // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1766
- // finalData.filters = {
1767
- // [`parent.${this.id}`]: { "$exists": true },
1768
- // };
1769
- } else {
1770
- delete finalData?.pathParams;
1771
- finalData.filters = {
1772
- [`parent.${this.id}`]: { "$exists": true },
1773
- };
1774
- }
1827
+ // return this._paginateWith(data, isNext, async (finalData) => {
1828
+ // if(this.isMe){
1829
+ // finalData.pathParams = { type: this.getEntityType(), id: this.id };
1830
+ // // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1831
+ // // finalData.filters = {
1832
+ // // [`parent.${this.id}`]: { "$exists": true },
1833
+ // // };
1834
+ // } else {
1835
+ // delete finalData?.pathParams;
1836
+ // finalData.filters = {
1837
+ // [`parent.${this.id}`]: { "$exists": true },
1838
+ // };
1839
+ // }
1840
+
1841
+ // const fetchFn = this.isMe
1842
+ // ? () => this.callIsMe(() => this.endpointApi.getPoisAdmin(finalData))
1843
+ // : () => this.endpointApi.getPoisNoAdmin(finalData);
1844
+
1845
+ // return fetchFn();
1846
+ // });
1847
+
1848
+ const paginator = this._createPaginatorEngine({
1849
+ initialData: data,
1850
+ finalizer: async (finalData) => {
1851
+ if(this.isMe){
1852
+ finalData.pathParams = { type: this.getEntityType(), id: this.id };
1853
+ // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1854
+ // finalData.filters = {
1855
+ // [`parent.${this.id}`]: { "$exists": true },
1856
+ // };
1857
+ } else {
1858
+ delete finalData?.pathParams;
1859
+ finalData.filters = {
1860
+ [`parent.${this.id}`]: { "$exists": true },
1861
+ };
1862
+ }
1775
1863
 
1776
- const fetchFn = this.isMe
1777
- ? () => this.callIsMe(() => this.endpointApi.getPoisAdmin(finalData))
1778
- : () => this.endpointApi.getPoisNoAdmin(finalData);
1864
+ const fetchFn = this.isMe
1865
+ ? () => this.callIsMe(() => this.endpointApi.getPoisAdmin(finalData))
1866
+ : () => this.endpointApi.getPoisNoAdmin(finalData);
1779
1867
 
1780
- return fetchFn();
1868
+ return fetchFn();
1869
+ }
1781
1870
  });
1871
+
1872
+ return paginator.next();
1782
1873
  }
1783
1874
 
1784
1875
  /**
@@ -1788,20 +1879,36 @@ export class BaseEntity {
1788
1879
  * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1789
1880
  * @returns {Promise<Object>} - Les données de réponse.
1790
1881
  */
1791
- async getSubscribers(data = {}, isNext = false) {
1882
+ async getSubscribers(data = {}) {
1792
1883
  data.searchType = this._getDefaultFromEndpoint("GET_SUBSCRIBERS", "searchType");
1793
1884
  // data.searchBy = "ALL";
1794
- return this._paginateWith(data, isNext, async (finalData) => {
1795
- delete finalData?.pathParams;
1885
+ // return this._paginateWith(data, isNext, async (finalData) => {
1886
+ // delete finalData?.pathParams;
1887
+
1888
+ // finalData.filters = {
1889
+ // [`links.follows.${this.id}`]: { "$exists": true },
1890
+ // [`links.follows.${this.id}.toBeValidated`]: { "$exists": false },
1891
+ // [`links.follows.${this.id}.isInviting`]: { "$exists": false }
1892
+ // };
1893
+
1894
+ // return this.endpointApi.getSubscribers(finalData);
1895
+ // });
1896
+ const paginator = this._createPaginatorEngine({
1897
+ initialData: data,
1898
+ finalizer: async (finalData) => {
1899
+ delete finalData?.pathParams;
1796
1900
 
1797
- finalData.filters = {
1798
- [`links.follows.${this.id}`]: { "$exists": true },
1799
- [`links.follows.${this.id}.toBeValidated`]: { "$exists": false },
1800
- [`links.follows.${this.id}.isInviting`]: { "$exists": false }
1801
- };
1901
+ finalData.filters = {
1902
+ [`links.follows.${this.id}`]: { "$exists": true },
1903
+ [`links.follows.${this.id}.toBeValidated`]: { "$exists": false },
1904
+ [`links.follows.${this.id}.isInviting`]: { "$exists": false }
1905
+ };
1802
1906
 
1803
- return this.endpointApi.getSubscribers(finalData);
1907
+ return this.endpointApi.getSubscribers(finalData);
1908
+ }
1804
1909
  });
1910
+
1911
+ return paginator.next();
1805
1912
  }
1806
1913
 
1807
1914
  /**
@@ -1811,18 +1918,32 @@ export class BaseEntity {
1811
1918
  * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1812
1919
  * @returns {Promise<Object>} - Les données de réponse.
1813
1920
  */
1814
- async getBadgesIssuer(data = {}, isNext = false) {
1921
+ async getBadgesIssuer(data = {}) {
1815
1922
  data.searchType = this._getDefaultFromEndpoint("GET_BADGES", "searchType");
1816
1923
  // data.searchBy = "ALL";
1817
- return this._paginateWith(data, isNext, async (finalData) => {
1818
- delete finalData?.pathParams;
1924
+ // return this._paginateWith(data, isNext, async (finalData) => {
1925
+ // delete finalData?.pathParams;
1926
+
1927
+ // finalData.filters = finalData.filters || {};
1928
+ // finalData.filters["$or"] = {};
1929
+ // finalData.filters["$or"][`issuer.${this.id}`] = { "$exists": true };
1930
+
1931
+ // return this.endpointApi.getBadges(finalData);
1932
+ // });
1933
+ const paginator = this._createPaginatorEngine({
1934
+ initialData: data,
1935
+ finalizer: async (finalData) => {
1936
+ delete finalData?.pathParams;
1819
1937
 
1820
- finalData.filters = finalData.filters || {};
1821
- finalData.filters["$or"] = {};
1822
- finalData.filters["$or"][`issuer.${this.id}`] = { "$exists": true };
1938
+ finalData.filters = finalData.filters || {};
1939
+ finalData.filters["$or"] = {};
1940
+ finalData.filters["$or"][`issuer.${this.id}`] = { "$exists": true };
1823
1941
 
1824
- return this.endpointApi.getBadges(finalData);
1942
+ return this.endpointApi.getBadges(finalData);
1943
+ }
1825
1944
  });
1945
+
1946
+ return paginator.next();
1826
1947
  }
1827
1948
 
1828
1949
  /**
@@ -2197,109 +2318,109 @@ export class BaseEntity {
2197
2318
  * @throws {ApiResponseError} - Si les résultats ne sont pas un tableau.
2198
2319
  * @private
2199
2320
  */
2200
- async _paginateWith(data = {}, isNext = false, finalizer) {
2201
- if (!this.serverData.slug) throw new ApiError("slug de l'entité non défini");
2202
- if (!this.serverData.id) throw new ApiError("id de l'entité non défini");
2203
-
2204
- const hasStep = (d) => d?.indexStep && d.indexStep > 0;
2205
-
2206
- if (!this._paginationCursor || (!isNext && this._paginationHistory.length === 0)) {
2207
- this._paginationCount = 0;
2208
- this._paginationPageIndex = 0;
2209
- this._paginationHistory = [];
2210
- this._paginationPageSizes = [];
2211
- data.countType = data.searchType;
2212
-
2213
- if (!data?.searchBy && hasStep(data)) {
2214
- data.ranges = this._generateRanges(data.searchType, data.indexStep);
2215
- data.indexMin = data.indexMin ?? 0;
2216
- data.indexMax = data.indexMax ?? data.indexStep;
2217
- } else if (data?.searchBy === "ALL" && hasStep(data)) {
2218
- data.indexMin = data.indexMin ?? 0;
2219
- data.indexMax = data.indexMax ?? data.indexStep;
2220
- }
2221
-
2222
- this._paginationCursor = { ...data };
2223
- }
2321
+ // async _paginateWith(data = {}, isNext = false, finalizer) {
2322
+ // if (!this.serverData.slug) throw new ApiError("slug de l'entité non défini");
2323
+ // if (!this.serverData.id) throw new ApiError("id de l'entité non défini");
2324
+
2325
+ // const hasStep = (d) => d?.indexStep && d.indexStep > 0;
2326
+
2327
+ // if (!this._paginationCursor || (!isNext && this._paginationHistory.length === 0)) {
2328
+ // this._paginationCount = 0;
2329
+ // this._paginationPageIndex = 0;
2330
+ // this._paginationHistory = [];
2331
+ // this._paginationPageSizes = [];
2332
+ // data.countType = data.searchType;
2333
+
2334
+ // if (!data?.searchBy && hasStep(data)) {
2335
+ // data.ranges = this._generateRanges(data.searchType, data.indexStep);
2336
+ // data.indexMin = data.indexMin ?? 0;
2337
+ // data.indexMax = data.indexMax ?? data.indexStep;
2338
+ // } else if (data?.searchBy === "ALL" && hasStep(data)) {
2339
+ // data.indexMin = data.indexMin ?? 0;
2340
+ // data.indexMax = data.indexMax ?? data.indexStep;
2341
+ // }
2342
+
2343
+ // this._paginationCursor = { ...data };
2344
+ // }
2224
2345
 
2225
- const cursor = this._paginationCursor;
2346
+ // const cursor = this._paginationCursor;
2226
2347
 
2227
- if (isNext) {
2228
- this._paginationHistory.push({ ...cursor });
2348
+ // if (isNext) {
2349
+ // this._paginationHistory.push({ ...cursor });
2229
2350
 
2230
- if (!cursor.searchBy && hasStep(cursor)) {
2231
- cursor.ranges = this._generateRanges(cursor.searchType, cursor.indexStep, cursor.ranges);
2232
- cursor.indexMin = cursor.indexMax ?? 0;
2233
- cursor.indexMax = (cursor.indexMax ?? 0) + cursor.indexStep;
2234
- } else if (cursor.searchBy === "ALL" && hasStep(cursor)) {
2235
- cursor.indexMin = cursor.indexMax ?? 0;
2236
- cursor.indexMax = (cursor.indexMax ?? 0) + cursor.indexStep;
2237
- }
2351
+ // if (!cursor.searchBy && hasStep(cursor)) {
2352
+ // cursor.ranges = this._generateRanges(cursor.searchType, cursor.indexStep, cursor.ranges);
2353
+ // cursor.indexMin = cursor.indexMax ?? 0;
2354
+ // cursor.indexMax = (cursor.indexMax ?? 0) + cursor.indexStep;
2355
+ // } else if (cursor.searchBy === "ALL" && hasStep(cursor)) {
2356
+ // cursor.indexMin = cursor.indexMax ?? 0;
2357
+ // cursor.indexMax = (cursor.indexMax ?? 0) + cursor.indexStep;
2358
+ // }
2238
2359
 
2239
- this._paginationCursor = { ...cursor };
2240
- }
2360
+ // this._paginationCursor = { ...cursor };
2361
+ // }
2241
2362
 
2242
- data = { ...this._paginationCursor };
2363
+ // data = { ...this._paginationCursor };
2243
2364
 
2244
- if (!isNext && (!data?.searchType || !Array.isArray(data.searchType) || data.searchType.length === 0)) {
2245
- throw new ApiError("searchType non défini");
2246
- }
2365
+ // if (!isNext && (!data?.searchType || !Array.isArray(data.searchType) || data.searchType.length === 0)) {
2366
+ // throw new ApiError("searchType non défini");
2367
+ // }
2247
2368
 
2248
- const result = await finalizer(data);
2249
- if (!Array.isArray(result.results)) {
2250
- throw new ApiResponseError("Erreur lors de la récupération des résultats", 500, result.results);
2251
- }
2369
+ // const result = await finalizer(data);
2370
+ // if (!Array.isArray(result.results)) {
2371
+ // throw new ApiResponseError("Erreur lors de la récupération des résultats", 500, result.results);
2372
+ // }
2252
2373
 
2253
- this._paginationCount += result.results.length;
2254
- this._paginationPageSizes.push(result.results.length);
2374
+ // this._paginationCount += result.results.length;
2375
+ // this._paginationPageSizes.push(result.results.length);
2255
2376
 
2256
- if (isNext) {
2257
- this._paginationPageIndex++;
2258
- }
2377
+ // if (isNext) {
2378
+ // this._paginationPageIndex++;
2379
+ // }
2259
2380
 
2260
- const count = this._normalizeCount(result.count);
2261
- const rawList = this._linkEntities(result.results);
2262
- const hasNext = hasStep(data) && this._paginationCount < count.total;
2263
- const hasPrev = this._paginationHistory?.length > 0;
2264
-
2265
- const response = {
2266
- count,
2267
- results: rawList,
2268
- pageIndex: this._paginationPageIndex,
2269
- pageNumber: this._paginationPageIndex + 1,
2270
- hasNext,
2271
- hasPrev
2272
- };
2273
-
2274
- if (hasNext) {
2275
- response.next = async () => this._paginateWith({}, true, finalizer);
2276
- }
2381
+ // const count = this._normalizeCount(result.count);
2382
+ // const rawList = this._linkEntities(result.results);
2383
+ // const hasNext = hasStep(data) && this._paginationCount < count.total;
2384
+ // const hasPrev = this._paginationHistory?.length > 0;
2385
+
2386
+ // const response = {
2387
+ // count,
2388
+ // results: rawList,
2389
+ // pageIndex: this._paginationPageIndex,
2390
+ // pageNumber: this._paginationPageIndex + 1,
2391
+ // hasNext,
2392
+ // hasPrev
2393
+ // };
2394
+
2395
+ // if (hasNext) {
2396
+ // response.next = async () => this._paginateWith({}, true, finalizer);
2397
+ // }
2277
2398
 
2278
- if (this._paginationHistory?.length > 0) {
2279
- response.prev = async () => {
2280
- const previous = this._paginationHistory.pop();
2281
- const lastPageSize = this._paginationPageSizes.pop() ?? 0;
2282
- this._paginationCount -= lastPageSize;
2283
- this._paginationPageIndex = Math.max(0, this._paginationPageIndex - 1);
2284
- this._paginationCursor = { ...previous };
2285
- return this._paginateWith({}, false, finalizer);
2286
- };
2287
- }
2399
+ // if (this._paginationHistory?.length > 0) {
2400
+ // response.prev = async () => {
2401
+ // const previous = this._paginationHistory.pop();
2402
+ // const lastPageSize = this._paginationPageSizes.pop() ?? 0;
2403
+ // this._paginationCount -= lastPageSize;
2404
+ // this._paginationPageIndex = Math.max(0, this._paginationPageIndex - 1);
2405
+ // this._paginationCursor = { ...previous };
2406
+ // return this._paginateWith({}, false, finalizer);
2407
+ // };
2408
+ // }
2288
2409
 
2289
- return response;
2290
- }
2410
+ // return response;
2411
+ // }
2291
2412
 
2292
2413
 
2293
2414
  /**
2294
2415
  * Réinitialise l'état de pagination.
2295
2416
  */
2296
- resetPagination() {
2297
- this._paginationCursor = undefined;
2298
- this._paginationCount = 0;
2299
- this._paginationPageIndex = 0;
2300
- this._paginationHistory = [];
2301
- this._paginationPageSizes = [];
2302
- }
2417
+ // resetPagination() {
2418
+ // this._paginationCursor = undefined;
2419
+ // this._paginationCount = 0;
2420
+ // this._paginationPageIndex = 0;
2421
+ // this._paginationHistory = [];
2422
+ // this._paginationPageSizes = [];
2423
+ // }
2303
2424
 
2304
2425
 
2305
2426
  /**
@@ -2323,23 +2444,167 @@ export class BaseEntity {
2323
2444
  * @returns {Promise<Object>} - Résultat de la recherche.
2324
2445
  * @throws {ApiError} - Si le slug ou l'id de entité n'est pas défini.
2325
2446
  */
2326
- async searchCostum(data = {}, isNext = false) {
2327
- return this._paginateWith(data, isNext, async (finalData) => {
2328
- finalData = {
2329
- ...finalData,
2330
- costumSlug: this.serverData.slug,
2331
- contextId: this.serverData.id,
2332
- contextType: this.getEntityType()
2333
- };
2447
+ // async searchCostum(data = {}, isNext = false) {
2448
+ // return this._paginateWith(data, isNext, async (finalData) => {
2449
+ // finalData = {
2450
+ // ...finalData,
2451
+ // costumSlug: this.serverData.slug,
2452
+ // contextId: this.serverData.id,
2453
+ // contextType: this.getEntityType()
2454
+ // };
2334
2455
 
2335
- if (finalData.sourceKey?.length) {
2336
- finalData.sourceKey = [...finalData.sourceKey, this.serverData.slug];
2337
- } else {
2338
- finalData.sourceKey = [this.serverData.slug];
2339
- }
2456
+ // if (finalData.sourceKey?.length) {
2457
+ // finalData.sourceKey = [...finalData.sourceKey, this.serverData.slug];
2458
+ // } else {
2459
+ // finalData.sourceKey = [this.serverData.slug];
2460
+ // }
2340
2461
 
2341
- return this.endpointApi.globalAutocompleteCostum(finalData);
2462
+ // return this.endpointApi.globalAutocompleteCostum(finalData);
2463
+ // });
2464
+ // }
2465
+
2466
+ /**
2467
+ * Recherche liée à l'entité, version stateless.
2468
+ *
2469
+ * @param {Object} data - Données initiales de recherche.
2470
+ * @returns {Object} - Un paginateur avec .next(), .prev(), etc.
2471
+ */
2472
+ async searchCostum(data = {}) {
2473
+
2474
+ const paginator = this._createPaginatorEngine({
2475
+ initialData: data,
2476
+ finalizer: this._withCostumContext((finalData) => this.endpointApi.globalAutocompleteCostum(finalData)),
2342
2477
  });
2478
+
2479
+ return paginator.next();
2480
+ }
2481
+
2482
+ /**
2483
+ * Coeur de pagination stateless et réutilisable, sans logique métier.
2484
+ *
2485
+ * @param {Object} config
2486
+ * @param {Object} config.initialData - Paramètres de départ
2487
+ * @param {Function} config.finalizer - Fonction async qui retourne { results, count }
2488
+ *
2489
+ * @returns {Object} paginator avec .next() et .prev()
2490
+ */
2491
+ _createPaginatorEngine({ initialData, finalizer }) {
2492
+ const Entity = this;
2493
+
2494
+ const state = {
2495
+ cursor: undefined,
2496
+ count: 0,
2497
+ index: 0,
2498
+ history: [],
2499
+ sizes: []
2500
+ };
2501
+
2502
+ const hasStep = (d) => d?.indexStep && d.indexStep > 0;
2503
+
2504
+ async function getPage(isNext = false) {
2505
+ let data = { ...initialData };
2506
+
2507
+ if (!state.cursor || (!isNext && state.history.length === 0)) {
2508
+ state.count = 0;
2509
+ state.index = 0;
2510
+ state.history = [];
2511
+ state.sizes = [];
2512
+
2513
+ data.countType = data.searchType;
2514
+
2515
+ if (!data?.searchBy && hasStep(data)) {
2516
+ data.ranges = Entity._generateRanges(data.searchType, data.indexStep);
2517
+ data.indexMin = data.indexMin ?? 0;
2518
+ data.indexMax = data.indexMax ?? data.indexStep;
2519
+ } else if (data?.searchBy === "ALL" && hasStep(data)) {
2520
+ data.indexMin = data.indexMin ?? 0;
2521
+ data.indexMax = data.indexMax ?? data.indexStep;
2522
+ }
2523
+
2524
+ state.cursor = { ...data };
2525
+ }
2526
+
2527
+ const cursor = state.cursor;
2528
+
2529
+ if (isNext) {
2530
+ state.history.push({ ...cursor });
2531
+
2532
+ if (!cursor.searchBy && hasStep(cursor)) {
2533
+ cursor.ranges = Entity._generateRanges(cursor.searchType, cursor.indexStep, cursor.ranges);
2534
+ cursor.indexMin = cursor.indexMax ?? 0;
2535
+ cursor.indexMax = (cursor.indexMax ?? 0) + cursor.indexStep;
2536
+ } else if (cursor.searchBy === "ALL" && hasStep(cursor)) {
2537
+ cursor.indexMin = cursor.indexMax ?? 0;
2538
+ cursor.indexMax = (cursor.indexMax ?? 0) + cursor.indexStep;
2539
+ }
2540
+
2541
+ state.cursor = { ...cursor };
2542
+ }
2543
+
2544
+ data = { ...state.cursor };
2545
+
2546
+ if (!isNext && (!data?.searchType || !Array.isArray(data.searchType) || data.searchType.length === 0)) {
2547
+ throw new Error("searchType non défini");
2548
+ }
2549
+
2550
+ const result = await finalizer(data);
2551
+ if (!Array.isArray(result.results)) {
2552
+ throw new Error("Les résultats doivent être un tableau");
2553
+ }
2554
+
2555
+ state.count += result.results.length;
2556
+ state.sizes.push(result.results.length);
2557
+ if (isNext) state.index++;
2558
+
2559
+ const count = Entity._normalizeCount(result.count);
2560
+ const rawList = Entity._linkEntities(result.results);
2561
+
2562
+ const hasNext = hasStep(data) && state.count < count.total;
2563
+ const hasPrev = state.history.length > 0;
2564
+
2565
+ return {
2566
+ count,
2567
+ results: rawList,
2568
+ pageIndex: state.index,
2569
+ pageNumber: state.index + 1,
2570
+ hasNext,
2571
+ hasPrev,
2572
+ next: hasNext ? () => getPage(true) : undefined,
2573
+ prev: hasPrev
2574
+ ? async () => {
2575
+ const previous = state.history.pop();
2576
+ const lastPageSize = state.sizes.pop() ?? 0;
2577
+ state.count -= lastPageSize;
2578
+ state.index = Math.max(0, state.index - 1);
2579
+ state.cursor = { ...previous };
2580
+ return getPage(false);
2581
+ }
2582
+ : undefined
2583
+ };
2584
+ }
2585
+
2586
+ return {
2587
+ next: () => getPage(false)
2588
+ };
2589
+ }
2590
+
2591
+ /**
2592
+ * Injection de contexte Communecter dans une requête finalizer.
2593
+ *
2594
+ * @param {Function} baseFinalizer - fonction async(data) => { results, count }
2595
+ * @returns {Function} fonction enrichie
2596
+ */
2597
+ _withCostumContext(baseFinalizer) {
2598
+ return async (data) => {
2599
+ const finalData = {
2600
+ ...data,
2601
+ costumSlug: this.serverData.slug,
2602
+ contextId: this.serverData.id,
2603
+ contextType: this.getEntityType(),
2604
+ sourceKey: [...(data.sourceKey || []), this.serverData.slug]
2605
+ };
2606
+ return baseFinalizer(finalData);
2607
+ };
2343
2608
  }
2344
2609
 
2345
2610