@communecter/cocolight-api-client 1.0.29 → 1.0.31

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@communecter/cocolight-api-client",
3
- "version": "1.0.29",
3
+ "version": "1.0.31",
4
4
  "description": "Client Axios simplifié pour l'API cocolight",
5
5
  "repository": {
6
6
  "type": "git",
package/src/Api.js CHANGED
@@ -163,7 +163,7 @@ export default class Api {
163
163
  */
164
164
  async project(projectData) {
165
165
  try {
166
- const project = new Project(this._client, projectData, { EndpointApi, User, Event, Poi, Badge, News });
166
+ const project = new Project(this._client, projectData, { EndpointApi, User, Organization, Event, Poi, Badge, News });
167
167
  if (!projectData.id && !projectData.slug) {
168
168
  throw new Error("Vous devez fournir un id ou un slug pour créer une instance Project.");
169
169
  }
package/src/api/Badge.js CHANGED
@@ -4,6 +4,8 @@ import BaseEntity from "./BaseEntity.js";
4
4
  export class Badge extends BaseEntity {
5
5
  static entityType = "badges";
6
6
 
7
+ static entityTag = "Badge";
8
+
7
9
  static SCHEMA_CONSTANTS = [
8
10
  "ADD_BADGES",
9
11
  ];
@@ -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") {
@@ -1002,7 +1004,14 @@ export class BaseEntity {
1002
1004
  * @private
1003
1005
  */
1004
1006
  _linkEntities(results) {
1005
- return results.map(d => this._linkEntity?.(d.collection, d) ?? d);
1007
+ return results.flatMap(d => {
1008
+ if (!d?.collection) {
1009
+ this.apiClient._logger?.warn?.(`Objet ignoré car sans 'collection' : ${d?.id}`);
1010
+ return []; // exclu de la liste
1011
+ }
1012
+
1013
+ return [this._linkEntity?.(d.collection, d) ?? d];
1014
+ });
1006
1015
  }
1007
1016
 
1008
1017
  /**
@@ -1670,193 +1679,152 @@ export class BaseEntity {
1670
1679
  * Récupérer les organisations d'une entitée : la liste des organisations dont l'entité est membre ou admin valide.
1671
1680
  * Constant : GET_ORGANIZATIONS_ADMIN | GET_ORGANIZATIONS_NO_ADMIN
1672
1681
  * @param {Object} data - Les données à envoyer.
1682
+ * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1673
1683
  * @returns {Promise<Object>} - Les données de réponse.
1674
1684
  */
1675
- async getOrganizations(data = {}) {
1676
-
1677
- if(this.isMe){
1678
- data.pathParams = { type: this.getEntityType(), id: this.id };
1679
- // NOTE : dans le schema je crois que si pas de data.filters alors le default ce fait avec data.pathParams
1680
- // data.filters = {
1681
- // [`links.members.${this.id}`]: { "$exists": true },
1682
- // [`links.members.${this.id}.toBeValidated`]: { "$exists": false },
1683
- // [`links.members.${this.id}.isInviting`]: { "$exists": false }
1684
- // };
1685
- } else {
1686
- delete data?.pathParams;
1687
- data.filters = {
1688
- [`links.members.${this.id}`]: { "$exists": true },
1689
- [`links.members.${this.id}.toBeValidated`]: { "$exists": false },
1690
- [`links.members.${this.id}.isInviting`]: { "$exists": false }
1691
- };
1692
- }
1693
-
1694
- const fetchFn = this.isMe
1695
- ? () => this.callIsMe(() => this.endpointApi.getOrganizationsAdmin(data))
1696
- : () => this.endpointApi.getOrganizationsNoAdmin(data);
1697
-
1698
- const arrayObjet = await fetchFn();
1699
-
1700
- if (!Array.isArray(arrayObjet.results)) {
1701
- throw new ApiResponseError("Erreur lors de la récupération des organisations.", 500, arrayObjet.results);
1702
- }
1703
-
1704
- // nettoyage du count
1705
- delete arrayObjet?.count?.spam;
1706
-
1707
- // calcul du total
1708
- const totalCount = Object.values(arrayObjet.count || {}).reduce((acc, val) => acc + val, 0);
1709
- arrayObjet.count.total = totalCount;
1710
-
1711
- const rawList = this._linkEntities(arrayObjet.results);
1685
+ async getOrganizations(data = {}, isNext = false) {
1686
+ data.searchType = this._getDefaultFromEndpoint("GET_ORGANIZATIONS_NO_ADMIN", "searchType");
1687
+ // data.searchBy = "ALL";
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
+ }
1712
1705
 
1713
- return {
1714
- count: arrayObjet.count,
1715
- results: rawList
1716
- };
1706
+ const fetchFn = this.isMe
1707
+ ? () => this.callIsMe(() => this.endpointApi.getOrganizationsAdmin(finalData))
1708
+ : () => this.endpointApi.getOrganizationsNoAdmin(finalData);
1709
+
1710
+ return fetchFn();
1711
+ });
1717
1712
  }
1718
1713
 
1719
1714
  /**
1720
- * Récupérer les projets d'une entitée : liste des projets de l'entité ou elle est "parent" ou "contributeur".
1721
- * Constant : GET_PROJECTS_ADMIN | GET_PROJECTS_NO_ADMIN
1722
- * @param {Object} data - Les données à envoyer.
1723
- * @returns {Promise<Object>} - Les données de réponse.
1724
- */
1725
- async getProjects(data = {}) {
1726
-
1727
- if(this.isMe){
1728
- data.pathParams = { type: this.getEntityType(), id: this.id };
1729
- // NOTE : dans le schema je crois que si pas de data.filters alors le default ce fait avec data.pathParams
1730
- // data.filters = {
1715
+ * Récupérer les projets d'une entitée : liste des projets de l'entité ou elle est "parent" ou "contributeur".
1716
+ * Constant : GET_PROJECTS_ADMIN | GET_PROJECTS_NO_ADMIN
1717
+ * @param {Object} data - Les données à envoyer.
1718
+ * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1719
+ * @returns {Promise<Object>} - Les données de réponse.
1720
+ */
1721
+ async getProjects(data = {}, isNext = false) {
1722
+ data.searchType = this._getDefaultFromEndpoint("GET_PROJECTS_ADMIN", "searchType");
1723
+ // data.searchBy = "ALL";
1724
+ return this._paginateWith(data, isNext, async (finalData) => {
1725
+ if(this.isMe){
1726
+ finalData.pathParams = { type: this.getEntityType(), id: this.id };
1727
+ // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1728
+ // finalData.filters = {
1731
1729
  // "$or": {
1732
1730
  // [`links.contributors.${this.id}`]: { "$exists": true },
1733
1731
  // [`parent.${this.id}`]: { "$exists": true }
1734
1732
  // },
1735
1733
  // [`links.contributors.${this.id}`]: { "$exists": true }
1736
1734
  // };
1737
- } else {
1738
- delete data?.pathParams;
1739
- data.filters = {
1740
- "$or": {
1741
- [`links.contributors.${this.id}`]: { "$exists": true },
1742
- [`parent.${this.id}`]: { "$exists": true }
1743
- },
1744
- [`links.contributors.${this.id}`]: { "$exists": true }
1745
- };
1746
- }
1747
-
1748
- const fetchFn = this.isMe
1749
- ? () => this.callIsMe(() => this.endpointApi.getProjectsAdmin(data))
1750
- : () => this.endpointApi.getProjectsNoAdmin(data);
1751
-
1752
-
1753
- const arrayObjet = await fetchFn();
1735
+ } else {
1736
+ delete finalData?.pathParams;
1737
+ finalData.filters = {
1738
+ "$or": {
1739
+ [`links.contributors.${this.id}`]: { "$exists": true },
1740
+ [`parent.${this.id}`]: { "$exists": true }
1741
+ },
1742
+ [`links.contributors.${this.id}`]: { "$exists": true }
1743
+ };
1744
+ }
1754
1745
 
1755
- if (!Array.isArray(arrayObjet.results)) {
1756
- throw new ApiResponseError("Erreur lors de la récupération des projets.", 500, arrayObjet.results);
1757
- }
1746
+ const fetchFn = this.isMe
1747
+ ? () => this.callIsMe(() => this.endpointApi.getProjectsAdmin(finalData))
1748
+ : () => this.endpointApi.getProjectsNoAdmin(finalData);
1758
1749
 
1759
- const rawList = this._linkEntities(arrayObjet.results);
1760
-
1761
- return {
1762
- count: arrayObjet?.count?.projects ?? 0,
1763
- results: rawList
1764
- };
1750
+ return fetchFn();
1751
+ });
1765
1752
  }
1766
1753
 
1767
1754
  /**
1768
1755
  * Récupérer les POIs d'une entité : liste des POIs de l'entité ou elle est "parent".
1769
1756
  * Constant : GET_POIS_NO_ADMIN / GET_POIS_ADMIN
1770
1757
  * @param {Object} data - Les données à envoyer.
1758
+ * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1771
1759
  * @returns {Promise<Object>} - Les données de réponse.
1772
1760
  */
1773
- async getPois(data = {}) {
1774
-
1775
- if(this.isMe){
1776
- data.pathParams = { type: this.getEntityType(), id: this.id };
1777
- // NOTE : dans le schema je crois que si pas de data.filters alors le default ce fait avec data.pathParams
1778
- // data.filters = {
1761
+ async getPois(data = {}, isNext = false) {
1762
+ data.searchType = this._getDefaultFromEndpoint("GET_POIS_ADMIN", "searchType");
1763
+ // data.searchBy = "ALL";
1764
+ return this._paginateWith(data, isNext, async (finalData) => {
1765
+ if(this.isMe){
1766
+ finalData.pathParams = { type: this.getEntityType(), id: this.id };
1767
+ // NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
1768
+ // finalData.filters = {
1779
1769
  // [`parent.${this.id}`]: { "$exists": true },
1780
1770
  // };
1781
- } else {
1782
- delete data?.pathParams;
1783
- data.filters = {
1784
- [`parent.${this.id}`]: { "$exists": true },
1785
- };
1786
- }
1787
-
1788
- const fetchFn = this.isMe
1789
- ? () => this.callIsMe(() => this.endpointApi.getPoisAdmin(data))
1790
- : () => this.endpointApi.getPoisNoAdmin(data);
1771
+ } else {
1772
+ delete finalData?.pathParams;
1773
+ finalData.filters = {
1774
+ [`parent.${this.id}`]: { "$exists": true },
1775
+ };
1776
+ }
1791
1777
 
1792
- const arrayObjet = await fetchFn();
1793
- if (!Array.isArray(arrayObjet.results)) {
1794
- throw new ApiResponseError("Erreur lors de la récupération des POIs.", 500, arrayObjet.results);
1795
- }
1778
+ const fetchFn = this.isMe
1779
+ ? () => this.callIsMe(() => this.endpointApi.getPoisAdmin(finalData))
1780
+ : () => this.endpointApi.getPoisNoAdmin(finalData);
1796
1781
 
1797
- // lier les entités au objets
1798
- const rawList = this._linkEntities(arrayObjet.results);
1799
-
1800
- return {
1801
- count: arrayObjet.count?.poi ?? 0,
1802
- results: rawList
1803
- };
1782
+ return fetchFn();
1783
+ });
1804
1784
  }
1805
1785
 
1806
1786
  /**
1807
1787
  * Récupérer les abonnés d'une entité
1808
1788
  * Constant : GET_SUBSCRIBERS
1809
1789
  * @param {Object} data - Les données à envoyer.
1790
+ * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1810
1791
  * @returns {Promise<Object>} - Les données de réponse.
1811
1792
  */
1812
- async getSubscribers(data = {}) {
1813
- delete data?.pathParams;
1814
-
1815
- data.filters = {
1816
- [`links.follows.${this.id}`]: { "$exists": true },
1817
- [`links.follows.${this.id}.toBeValidated`]: { "$exists": false },
1818
- [`links.follows.${this.id}.isInviting`]: { "$exists": false }
1819
- };
1820
-
1821
- const arrayObjet = await this.endpointApi.getSubscribers(data);
1822
- if (!Array.isArray(arrayObjet.results)) {
1823
- throw new ApiResponseError("Erreur lors de la récupération des abonnés.", 500, arrayObjet.results);
1824
- }
1793
+ async getSubscribers(data = {}, isNext = false) {
1794
+ data.searchType = this._getDefaultFromEndpoint("GET_SUBSCRIBERS", "searchType");
1795
+ // data.searchBy = "ALL";
1796
+ return this._paginateWith(data, isNext, async (finalData) => {
1797
+ delete finalData?.pathParams;
1825
1798
 
1826
- // lier les entités au objets
1827
- const rawList = this._linkEntities(arrayObjet.results);
1799
+ finalData.filters = {
1800
+ [`links.follows.${this.id}`]: { "$exists": true },
1801
+ [`links.follows.${this.id}.toBeValidated`]: { "$exists": false },
1802
+ [`links.follows.${this.id}.isInviting`]: { "$exists": false }
1803
+ };
1828
1804
 
1829
- return {
1830
- count: arrayObjet.count,
1831
- results: rawList
1832
- };
1805
+ return this.endpointApi.getSubscribers(finalData);
1806
+ });
1833
1807
  }
1834
1808
 
1835
1809
  /**
1836
1810
  * Liste des badges créés par l'entité
1837
1811
  * Constant : GET_BADGES
1838
1812
  * @param {Object} data - Les données à envoyer.
1813
+ * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
1839
1814
  * @returns {Promise<Object>} - Les données de réponse.
1840
1815
  */
1841
- async getBadgesIssuer(data = {}) {
1842
- delete data?.pathParams;
1816
+ async getBadgesIssuer(data = {}, isNext = false) {
1817
+ data.searchType = this._getDefaultFromEndpoint("GET_BADGES", "searchType");
1818
+ // data.searchBy = "ALL";
1819
+ return this._paginateWith(data, isNext, async (finalData) => {
1820
+ delete finalData?.pathParams;
1843
1821
 
1844
- data.filters = data.filters || {};
1845
- data.filters["$or"] = {};
1846
- data.filters["$or"][`issuer.${this.id}`] = { "$exists": true };
1847
-
1848
- const arrayObjet = await this.endpointApi.getBadges(data);
1849
- if (!Array.isArray(arrayObjet.results)) {
1850
- throw new ApiResponseError("Erreur lors de la récupération des badges.", 500, arrayObjet.results);
1851
- }
1822
+ finalData.filters = finalData.filters || {};
1823
+ finalData.filters["$or"] = {};
1824
+ finalData.filters["$or"][`issuer.${this.id}`] = { "$exists": true };
1852
1825
 
1853
- // lier les entités au objets
1854
- const rawList = this._linkEntities(arrayObjet.results);
1855
-
1856
- return {
1857
- count: arrayObjet.count?.badges ?? 0,
1858
- results: rawList
1859
- };
1826
+ return this.endpointApi.getBadges(finalData);
1827
+ });
1860
1828
  }
1861
1829
 
1862
1830
  /**
@@ -2164,6 +2132,217 @@ export class BaseEntity {
2164
2132
  return this._isLinked("follows");
2165
2133
  }
2166
2134
 
2135
+ /**
2136
+ * Récupère le JSON personnalisé de l'entité
2137
+ *
2138
+ * @returns {Promise<Object>} - Le JSON personnalisé de l'entité.
2139
+ * @throws {ApiError} - Si le slug de l'entité n'est pas défini.
2140
+ */
2141
+ async getCostumJson() {
2142
+ if (!this.serverData.slug) {
2143
+ throw new ApiError("slug de l'entité non défini");
2144
+ }
2145
+ const data = {
2146
+ pathParams: {
2147
+ slug: this.serverData.slug
2148
+ }
2149
+ };
2150
+ return this.endpointApi.getCostumJson(data);
2151
+ }
2152
+
2153
+ /**
2154
+ * Génère des plages d'index pour la pagination.
2155
+ *
2156
+ * @param {Array<string>} searchType - Types de recherche.
2157
+ * @param {number} indexStep - Pas d'index.
2158
+ * @param {Object} previousRanges - Plages précédentes.
2159
+ * @returns {Object} - Plages d'index générées.
2160
+ * @private
2161
+ */
2162
+ _generateRanges(searchType, indexStep, previousRanges = {}) {
2163
+ const ranges = {};
2164
+ for (const type of searchType) {
2165
+ const previous = previousRanges[type] || { indexMax: 0 };
2166
+ ranges[type] = {
2167
+ indexMin: previous.indexMax || 0,
2168
+ indexMax: previous.indexMax + indexStep
2169
+ };
2170
+ }
2171
+ return ranges;
2172
+ }
2173
+
2174
+ /**
2175
+ * Normalise le compte des résultats.
2176
+ *
2177
+ * @param {Object} count - Compte des résultats.
2178
+ * @returns {Object} - Compte normalisé.
2179
+ * @private
2180
+ */
2181
+ _normalizeCount(count = {}) {
2182
+ // suppression des indésirables
2183
+ delete count.spam;
2184
+
2185
+ // calcul du total (somme des valeurs numériques)
2186
+ count.total = Object.values(count).reduce((acc, val) => acc + (typeof val === "number" ? val : 0), 0);
2187
+
2188
+ return count;
2189
+ }
2190
+
2191
+ /**
2192
+ * Méthode générique de pagination contextuelle avec support next / prev.
2193
+ *
2194
+ * @param {Object} data - Données d'entrée
2195
+ * @param {boolean} isNext - true si appel de page suivante
2196
+ * @param {Function} finalizer - fonction qui transforme et envoie les données (exécute la requête)
2197
+ * @returns {Promise<Object>} { count, results, next, prev }
2198
+ * @throws {ApiError} - Si le slug ou l'id de l'entité n'est pas défini.
2199
+ * @throws {ApiResponseError} - Si les résultats ne sont pas un tableau.
2200
+ * @private
2201
+ */
2202
+ async _paginateWith(data = {}, isNext = false, finalizer) {
2203
+ if (!this.serverData.slug) throw new ApiError("slug de l'entité non défini");
2204
+ if (!this.serverData.id) throw new ApiError("id de l'entité non défini");
2205
+
2206
+ const hasStep = (d) => d?.indexStep && d.indexStep > 0;
2207
+
2208
+ if (!this._paginationCursor || (!isNext && this._paginationHistory.length === 0)) {
2209
+ this._paginationCount = 0;
2210
+ this._paginationPageIndex = 0;
2211
+ this._paginationHistory = [];
2212
+ this._paginationPageSizes = [];
2213
+ data.countType = data.searchType;
2214
+
2215
+ if (!data?.searchBy && hasStep(data)) {
2216
+ data.ranges = this._generateRanges(data.searchType, data.indexStep);
2217
+ data.indexMin = data.indexMin ?? 0;
2218
+ data.indexMax = data.indexMax ?? data.indexStep;
2219
+ } else if (data?.searchBy === "ALL" && hasStep(data)) {
2220
+ data.indexMin = data.indexMin ?? 0;
2221
+ data.indexMax = data.indexMax ?? data.indexStep;
2222
+ }
2223
+
2224
+ this._paginationCursor = { ...data };
2225
+ }
2226
+
2227
+ const cursor = this._paginationCursor;
2228
+
2229
+ if (isNext) {
2230
+ this._paginationHistory.push({ ...cursor });
2231
+
2232
+ if (!cursor.searchBy && hasStep(cursor)) {
2233
+ cursor.ranges = this._generateRanges(cursor.searchType, cursor.indexStep, cursor.ranges);
2234
+ cursor.indexMin = cursor.indexMax ?? 0;
2235
+ cursor.indexMax = (cursor.indexMax ?? 0) + cursor.indexStep;
2236
+ } else if (cursor.searchBy === "ALL" && hasStep(cursor)) {
2237
+ cursor.indexMin = cursor.indexMax ?? 0;
2238
+ cursor.indexMax = (cursor.indexMax ?? 0) + cursor.indexStep;
2239
+ }
2240
+
2241
+ this._paginationCursor = { ...cursor };
2242
+ }
2243
+
2244
+ data = { ...this._paginationCursor };
2245
+
2246
+ if (!isNext && (!data?.searchType || !Array.isArray(data.searchType) || data.searchType.length === 0)) {
2247
+ throw new ApiError("searchType non défini");
2248
+ }
2249
+
2250
+ const result = await finalizer(data);
2251
+ if (!Array.isArray(result.results)) {
2252
+ throw new ApiResponseError("Erreur lors de la récupération des résultats", 500, result.results);
2253
+ }
2254
+
2255
+ this._paginationCount += result.results.length;
2256
+ this._paginationPageSizes.push(result.results.length);
2257
+
2258
+ if (isNext) {
2259
+ this._paginationPageIndex++;
2260
+ }
2261
+
2262
+ const count = this._normalizeCount(result.count);
2263
+ const rawList = this._linkEntities(result.results);
2264
+ const hasNext = hasStep(data) && this._paginationCount < count.total;
2265
+ const hasPrev = this._paginationHistory?.length > 0;
2266
+
2267
+ const response = {
2268
+ count,
2269
+ results: rawList,
2270
+ pageIndex: this._paginationPageIndex,
2271
+ pageNumber: this._paginationPageIndex + 1,
2272
+ hasNext,
2273
+ hasPrev
2274
+ };
2275
+
2276
+ if (hasNext) {
2277
+ response.next = async () => this._paginateWith({}, true, finalizer);
2278
+ }
2279
+
2280
+ if (this._paginationHistory?.length > 0) {
2281
+ response.prev = async () => {
2282
+ const previous = this._paginationHistory.pop();
2283
+ const lastPageSize = this._paginationPageSizes.pop() ?? 0;
2284
+ this._paginationCount -= lastPageSize;
2285
+ this._paginationPageIndex = Math.max(0, this._paginationPageIndex - 1);
2286
+ this._paginationCursor = { ...previous };
2287
+ return this._paginateWith({}, false, finalizer);
2288
+ };
2289
+ }
2290
+
2291
+ return response;
2292
+ }
2293
+
2294
+
2295
+ /**
2296
+ * Réinitialise l'état de pagination.
2297
+ */
2298
+ resetPagination() {
2299
+ this._paginationCursor = undefined;
2300
+ this._paginationCount = 0;
2301
+ this._paginationPageIndex = 0;
2302
+ this._paginationHistory = [];
2303
+ this._paginationPageSizes = [];
2304
+ }
2305
+
2306
+
2307
+ /**
2308
+ * Récupère une valeur par défaut depuis un endpoint donné.
2309
+ *
2310
+ * @param {string} constant - Le nom unique de l’endpoint (ex: "GET_ORGANIZATIONS_NO_ADMIN")
2311
+ * @param {string} path - Le chemin vers la propriété (ex: "searchType")
2312
+ * @returns {*} La valeur par défaut, ou undefined si non trouvée
2313
+ */
2314
+ _getDefaultFromEndpoint(constant, path) {
2315
+ const endpoint = this.apiClient._endpoints.find((ep) => ep.constant === constant);
2316
+ if (!endpoint?.request?.properties?.[path]) return undefined;
2317
+ return endpoint.request.properties[path].default;
2318
+ }
2319
+
2320
+ /**
2321
+ * recherche lié à l'entité.
2322
+ *
2323
+ * @param {Object} data - Les données de recherche.
2324
+ * @param {boolean} isNext - Indique si c'est une recherche suivante (pagination).
2325
+ * @returns {Promise<Object>} - Résultat de la recherche.
2326
+ * @throws {ApiError} - Si le slug ou l'id de entité n'est pas défini.
2327
+ */
2328
+ async searchCostum(data = {}, isNext = false) {
2329
+ return this._paginateWith(data, isNext, async (finalData) => {
2330
+ finalData = {
2331
+ ...finalData,
2332
+ costumSlug: this.serverData.slug,
2333
+ contextId: this.serverData.id,
2334
+ contextType: this.getEntityType()
2335
+ };
2336
+
2337
+ if (finalData.sourceKey?.length) {
2338
+ finalData.sourceKey = [...finalData.sourceKey, this.serverData.slug];
2339
+ } else {
2340
+ finalData.sourceKey = [this.serverData.slug];
2341
+ }
2342
+
2343
+ return this.endpointApi.globalAutocompleteCostum(finalData);
2344
+ });
2345
+ }
2167
2346
 
2168
2347
 
2169
2348
  }
@@ -1363,6 +1363,21 @@ class EndpointApi {
1363
1363
  return this.call("GET_COSTUM_JSON", data);
1364
1364
  }
1365
1365
 
1366
+ /**
1367
+ * Recherche globale lier à un costum : Effectue une recherche globale lier à un costum
1368
+ * Constant : GLOBAL_AUTOCOMPLETE_COSTUM
1369
+ * @param {import("./EndpointApi.types").GlobalAutocompleteCostumData} data - Données envoyées à l'API
1370
+ * @returns {Promise<Object>} - Les données de réponse.
1371
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
1372
+ * @throws {Error} - En cas d'erreur inattendue.
1373
+ */
1374
+ async globalAutocompleteCostum(data) {
1375
+ if (!data || typeof data !== "object") {
1376
+ throw new TypeError("Le paramètre data doit être un objet.");
1377
+ }
1378
+ return this.call("GLOBAL_AUTOCOMPLETE_COSTUM", data);
1379
+ }
1380
+
1366
1381
  }
1367
1382
 
1368
1383
  export default EndpointApi;