@communecter/cocolight-api-client 1.0.8 → 1.0.9

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.
@@ -0,0 +1,286 @@
1
+ import { ApiError } from "../error.js";
2
+ import { NewsMixin } from "../mixin/NewsMixin.js";
3
+ import { UtilMixin } from "../mixin/UtilMixin.js";
4
+
5
+ // News.js
6
+ export class News {
7
+ // Champs privés pour protéger l'état
8
+ #draftData = {};
9
+ // Data d'une news venant du serveur
10
+ #serverData = null;
11
+
12
+ /**
13
+ * Crée une instance de News.
14
+ * @param {(Organization|Project|User)} parent - L'instance de l'element parent (ex: Organization, Project, User).
15
+ * @param {Object} identifier - Objet contenant { id }
16
+ * @param {Object} deps - Dépendances injectées (ex: User).
17
+ * @param {EndpointApi} deps.EndpointApi - Classe EndpointApi pour éviter les dépendances circulaires.
18
+ * @param {User} deps.User - Classe User pour éviter les dépendances circulaires.
19
+ */
20
+
21
+ constructor(parent, data = {}, deps = {}) {
22
+ if(!deps.EndpointApi){
23
+ throw new ApiError("EndpointApi class must be injected to avoid circular dependency.");
24
+ }
25
+ if (!deps.User) {
26
+ throw new ApiError("User class must be injected to avoid circular dependency.");
27
+ }
28
+ if (!parent) {
29
+ throw new ApiError("Parent is required.");
30
+ }
31
+ this.deps = deps;
32
+ this.UserClass = deps.User;
33
+ this.apiClient = parent.apiClient;
34
+
35
+ // Gérer les deux cas : fonction constructeur ou instance
36
+ if (typeof deps.EndpointApi === "function") {
37
+ this.endpointApi = new deps.EndpointApi(this.apiClient);
38
+ } else if (typeof deps.EndpointApi === "object") {
39
+ this.endpointApi = deps.EndpointApi;
40
+ } else {
41
+ throw new ApiError("deps.EndpointApi doit être une classe ou une instance valide.");
42
+ }
43
+
44
+ this.#draftData = { ...data };
45
+ this.parent = parent;
46
+
47
+ }
48
+
49
+ // Getters en lecture seule pour chaque propriété
50
+ get id() {
51
+ return this.#draftData.id || null;
52
+ }
53
+
54
+ get isConnected() {
55
+ return this.apiClient.isConnected;
56
+ }
57
+
58
+ get draftData() {
59
+ return this.#draftData;
60
+ }
61
+
62
+ get serverData() {
63
+ return this.#serverData;
64
+ }
65
+
66
+ get userId() {
67
+ return this.apiClient.userId;
68
+ }
69
+
70
+ get isMe() {
71
+ return this.isConnected && this.userId === this.parent.id;
72
+ }
73
+
74
+ getEntityType() {
75
+ return "news";
76
+ }
77
+
78
+ static fromServerData(data, parent, deps) {
79
+ const instance = new News(parent, { id: data.id }, deps);
80
+
81
+ // Injecte les données serveur
82
+ instance.#serverData = { ...data };
83
+
84
+ // Construit les données draft à partir du serverData
85
+ instance.#draftData = instance._getDraftFromServerData(data);
86
+
87
+ return instance;
88
+ }
89
+
90
+ async refresh() {
91
+ if (!this.id) throw new ApiError("Impossible de rafraîchir sans ID.");
92
+ return this.get();
93
+ }
94
+
95
+ /**
96
+ * Récupérer des actualités par IDs : Récupère des actualités à partir d’une liste d’identifiants.
97
+ * Constant : GET_NEWS_BY_ID
98
+ */
99
+ async get() {
100
+ if(!this.id) {
101
+ throw new ApiError("Vous devez fournir un id pour récupérer une news.");
102
+ }
103
+ const newsArray = await this.callIsConnected(() => this.endpointApi.getNewsById({ ids: [this.id] }));
104
+ if (newsArray && newsArray.length > 0) {
105
+ this.#serverData = newsArray[0];
106
+ this.#draftData = this._getDraftFromServerData(this.#serverData);
107
+ return this.#serverData;
108
+ }
109
+ throw new ApiError(`Aucune actualité trouvée pour l'ID ${this.id}`);
110
+ }
111
+
112
+ _getDraftFromServerData(data) {
113
+ // je veux copier que certaine info si présente dans le draftData
114
+ // - newsArray[0].scope.type > draftData.scope
115
+ // - newsArray[0].text > draftData.text
116
+ // - newsArray[0].tags > draftData.tags
117
+ // - newsArray[0].mentions > draftData.mentions > draftData.mentions.count integer
118
+ // - newsArray[0].mediaImg > draftData.mediaImg > draftData.mediaImg.images > un array id
119
+ // - newsArray[0].mediaFile > draftData.mediaFile > draftData.mediaFile.files > un array id
120
+ const transformed = this._pickProps(
121
+ data,
122
+ ["scope", "text", "tags", "mentions", "mediaImg", "mediaFile"],
123
+ {
124
+ scope: (val) => val?.type,
125
+ mentions: (val) =>
126
+ Array.isArray(val)
127
+ ? val.map((mention) => ({
128
+ ...mention,
129
+ count: parseInt(mention.count)
130
+ }))
131
+ : [],
132
+ mediaImg: (val) => {
133
+ const images = val?.images?.map((img) => img.id).filter(Boolean) || [];
134
+ return images.length > 0
135
+ ? {
136
+ countImages: parseInt(val.countImages) || images.length,
137
+ images
138
+ }
139
+ : undefined;
140
+ },
141
+ mediaFile: (val) => {
142
+ const files = val?.files?.map((file) => file.id).filter(Boolean) || [];
143
+ return files.length > 0
144
+ ? {
145
+ countFiles: parseInt(val.countFiles) || files.length,
146
+ files
147
+ }
148
+ : undefined;
149
+ }
150
+ }
151
+ );
152
+
153
+ return {
154
+ id: data.id,
155
+ ...Object.fromEntries(Object.entries(transformed).filter(([, v]) => v !== undefined))
156
+ };
157
+ }
158
+
159
+ /**
160
+ * Ajouter une actualité : Ajoute une nouvelle actualité.
161
+ * Constant : ADD_NEWS | UPDATE_NEWS
162
+ */
163
+ async save() {
164
+
165
+ // si le texte est vide, on met un espace pour que le champ soit pris en compte car sur le serveur
166
+ // il y a une vérification de la taille du texte je pense
167
+ if(this.#draftData?.text === ""){
168
+ this.#draftData.text = " ";
169
+ }
170
+
171
+ const payload = { ...this.#draftData };
172
+ payload.parentId = this.parent.id;
173
+ payload.parentType = this.parent.getEntityType();
174
+
175
+ if (!this.id) {
176
+ const reponseData = await this.callIsConnected(() => this.endpointApi.addNews(payload));
177
+ this.#draftData.id = reponseData.object.id;
178
+ // TODO : voir si j'ai ce qui faut dans reponseData de ADD_NEWS pour mettre à jour #serverData
179
+ // c'est dans reponseData.object
180
+ if(reponseData?.object){
181
+ this.#serverData = { ...reponseData.object };
182
+ }
183
+ // await this.refresh();
184
+ return reponseData;
185
+ } else {
186
+ if(payload.id){
187
+ delete payload.id;
188
+ }
189
+ const reponseData = await this.callIsConnected(() => this.endpointApi.updateNews({ ...payload, idNews: this.id }));
190
+ // TODO : voir si j'ai ce qui faut dans reponseData de UPDATE_NEWS pour mettre à jour #serverData
191
+ // c'est dans reponseData.object
192
+ if(reponseData?.object){
193
+ this.#serverData = { ...reponseData.object };
194
+ }
195
+ // await this.refresh();
196
+ return reponseData;
197
+ }
198
+ }
199
+
200
+
201
+ async addMention({ slug, id }) {
202
+ try {
203
+ if (!slug && !id) {
204
+ throw new ApiError("Vous devez fournir un slug ou un id pour ajouter une mention.");
205
+ }
206
+ const userInstance = new this.UserClass(this.apiClient, { id, slug }, null , { EndpointApi: this.endpointApi });
207
+ const user = await userInstance.getProfil();
208
+ if (!this.#draftData.mentions) {
209
+ this.#draftData.mentions = [];
210
+ }
211
+ // Vérification si la mention existe déjà
212
+ if (this.#draftData.mentions.find((mention) => mention.id === user.id)) {
213
+ // Si la mention existe déjà, on incrémente le compteur
214
+ this.#draftData.mentions = this.#draftData.mentions.map((mention) => {
215
+ if (mention.id === user.id) {
216
+ mention.count += 1;
217
+ }
218
+ return mention;
219
+ });
220
+ return this.#draftData.mentions;
221
+ }
222
+ const mention = { id: user.id, slug: user.slug, type: userInstance.getEntityType(), name: user.name, value: user.name, count: 1 };
223
+ this.#draftData.mentions.push(mention);
224
+ return this.#draftData.mentions;
225
+ } catch (error) {
226
+ this.apiClient._logger.error("Erreur lors de l'ajout de la mention :", error);
227
+ throw error;
228
+ }
229
+
230
+ }
231
+
232
+ /**
233
+ * Ajouter une image à une actualité : Ajoute une images à une actualité.
234
+ * Constant : ADD_IMAGE_NEWS
235
+ */
236
+ async addImage(image) {
237
+ image = await this.validateImage(image);
238
+ const data = { pathParams: { folder: this.parent.getEntityType(), ownerId: this.parent.id }, newsImage: image };
239
+ const dataImage = await this.callIsConnected(() => this.endpointApi.addImageNews(data));
240
+ if (this.#draftData.mediaImg) {
241
+ this.#draftData.mediaImg.countImages = this.#draftData.mediaImg.countImages + 1;
242
+ this.#draftData.mediaImg.images.push(dataImage.id);
243
+ } else {
244
+ this.#draftData.mediaImg = { countImages: 1, images: [dataImage.id] };
245
+ }
246
+ return dataImage;
247
+ }
248
+
249
+ /**
250
+ * Ajouter un fichier à une actualité : Ajoute un fichier à une actualité.
251
+ * Constant : ADD_FILE_NEWS
252
+ */
253
+ async addFile(file) {
254
+ file = await this.validateFile(file);
255
+ const data = { pathParams: { folder: this.parent.getEntityType(), ownerId: this.parent.id }, newsFile: file };
256
+ const dataFile = await this.callIsConnected(() =>this.endpointApi.addFileNews(data));
257
+ if (this.#draftData.mediaFile) {
258
+ this.#draftData.mediaFile.countFiles = this.#draftData.mediaFile.countFiles + 1;
259
+ this.#draftData.mediaFile.files.push(dataFile);
260
+ } else {
261
+ this.#draftData.mediaFile = { countFiles: 1, files: [dataFile] };
262
+ }
263
+ return dataFile;
264
+ }
265
+
266
+ /**
267
+ * Supprimer une actualité : Supprime une actualité existante.
268
+ * Constant : DELETE_NEWS
269
+ */
270
+ async delete() {
271
+ if(!this.id) {
272
+ throw new ApiError("Vous devez fournir un id pour supprimer une news.");
273
+ }
274
+ const data = { pathParams: { id: this.id } };
275
+ await this.callIsConnected(() => this.endpointApi.deleteNews(data));
276
+ this.#draftData = {};
277
+ this.#serverData = null;
278
+ this.#draftData.id = null;
279
+ this._isDeleted = true;
280
+ }
281
+
282
+ }
283
+
284
+ // Incorporation du mixin dans Organization
285
+ Object.assign(News.prototype, UtilMixin, NewsMixin);
286
+
@@ -1,6 +1,9 @@
1
- import { EntityMixin } from "./EntityMixin.js";
2
- import { NewsMixin } from "./NewsMixin.js";
3
- import { UtilMixin } from "./UtilMixin.js";
1
+ import { ApiResponseError } from "../error.js";
2
+ import { News } from "./News.js";
3
+ import { User } from "./User.js";
4
+ import { EntityMixin } from "../mixin/EntityMixin.js";
5
+ import { NewsMixin } from "../mixin/NewsMixin.js";
6
+ import { UtilMixin } from "../mixin/UtilMixin.js";
4
7
 
5
8
  // Organization.js
6
9
  export class Organization {
@@ -13,13 +16,29 @@ export class Organization {
13
16
  * Crée une instance de Organization.
14
17
  * @param {ApiClient} apiClient - L'instance d'ApiClient.
15
18
  * @param {Object} identifier - Objet contenant { id } ou { slug }.
19
+ * @param {Object} [deps={}] - Dépendances injectées (ex: User).
20
+ * @param {EndpointApi} deps.EndpointApi - Classe EndpointApi pour éviter les dépendances circulaires.
16
21
  */
17
22
 
18
- constructor(apiClient, { id, slug } = {}) {
23
+ constructor(apiClient, { id, slug } = {}, deps = {}) {
24
+ if(!deps.EndpointApi){
25
+ throw new Error("EndpointApi class must be injected to avoid circular dependency.");
26
+ }
19
27
  if (!id && !slug) {
20
- throw new Error("Vous devez fournir un id ou un slug pour créer un User.");
28
+ throw new Error("Vous devez fournir un id ou un slug pour créer une instance User.");
21
29
  }
22
30
  this.apiClient = apiClient;
31
+ this.deps = deps;
32
+
33
+ // Gérer les deux cas : fonction constructeur ou instance
34
+ if (typeof deps.EndpointApi === "function") {
35
+ this.endpointApi = new deps.EndpointApi(this.apiClient);
36
+ } else if (typeof deps.EndpointApi === "object") {
37
+ this.endpointApi = deps.EndpointApi;
38
+ } else {
39
+ throw new Error("deps.EndpointApi doit être une classe ou une instance valide.");
40
+ }
41
+
23
42
  this.#id = id || null;
24
43
  this.#slug = slug || null;
25
44
  }
@@ -78,6 +97,98 @@ export class Organization {
78
97
  });
79
98
  }
80
99
 
100
+ /**
101
+ * Mettre à jour les paramètres d'un élément : Mise à jour des paramètres spécifiques d'un élément.
102
+ * Constant : UPDATE_SETTINGS
103
+ * @param {Object} data - Les données à envoyer.
104
+ * @param {string} data.type - data.type
105
+ * @param {undefined} data.value - data.value
106
+ * @returns {Promise<Object>} - Les données de réponse.
107
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
108
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
109
+ * @throws {Error} - En cas d'erreur inattendue.
110
+ */
111
+ async updateSettings(data = {}) {
112
+ data.idEntity = this.id;
113
+ data.typeEntity = this.getEntityType();
114
+ return this.callIsConnected(() => this.endpointApi.updateSettings(data));
115
+ }
116
+
117
+ /**
118
+ * Mettre à jour la description d'un élément : Permet de mettre à jour la description courte et complète d'un élément.
119
+ * Constant : UPDATE_BLOCK_DESCRIPTION
120
+ * @param {Object} data - Les données à envoyer.
121
+ * @param {string} data.descMentions - Mentions dans la description (default: "")
122
+ * @param {string} data.shortDescription - Courte description
123
+ * @param {string} data.description - Description complète
124
+ * @returns {Promise<Object>} - Les données de réponse.
125
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
126
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
127
+ * @throws {Error} - En cas d'erreur inattendue.
128
+ */
129
+ async updateDescription(data = {}) {
130
+ data.typeElement = this.getEntityType();
131
+ data.id = this.id;
132
+ return this.callIsConnected(() => this.endpointApi.updateBlockDescription(data));
133
+ }
134
+
135
+ /**
136
+ * Mettre à jour les informations d'un élément : Permet de mettre à jour les informations générales d'un élément (nom, contacts, etc.).
137
+ * Constant : UPDATE_BLOCK_INFO
138
+ */
139
+ async updateInfo(data = {}) {
140
+ data.typeElement = this.getEntityType();
141
+ data.id = this.id;
142
+ return this.callIsConnected(() => this.endpointApi.updateBlockInfo(data));
143
+ }
144
+
145
+ /**
146
+ * Mettre à jour les réseaux sociaux d'un élément : Permet de mettre à jour les liens vers les réseaux sociaux d'un élément.
147
+ * Constant : UPDATE_BLOCK_SOCIAL
148
+ */
149
+ async updateSocial(data = {}) {
150
+ data.typeElement = this.getEntityType();
151
+ data.id = this.id;
152
+ return this.callIsConnected(() => this.endpointApi.updateBlockSocial(data));
153
+ }
154
+
155
+ /**
156
+ * Mettre à jour les localités d'un élément : Permet de mettre à jour l'adresse et les informations géographiques d'un élément.
157
+ * Constant : UPDATE_BLOCK_LOCALITY
158
+ */
159
+ async updateLocality(data = {}) {
160
+ data.typeElement = this.getEntityType();
161
+ data.id = this.id;
162
+ return this.callIsConnected(() => this.endpointApi.updateBlockLocality(data));
163
+ }
164
+
165
+ /**
166
+ * Mettre à jour le slug d'un élément : Permet de mettre à jour le slug pour une URL simplifiée.
167
+ * Constant : UPDATE_BLOCK_SLUG
168
+ */
169
+ async updateSlug(slug) {
170
+ try {
171
+ await this.endpointApi.check({ slug });
172
+ } catch (error) {
173
+ if(error instanceof ApiResponseError) {
174
+ throw new ApiResponseError("Erreur lors de la vérification du slug.", error.status, error.data);
175
+ }
176
+ throw error;
177
+ }
178
+ const data = { typeElement: this.getEntityType(), id: this.id, slug };
179
+ return this.callIsConnected(() => this.endpointApi.updateBlockSlug(data));
180
+ }
181
+
182
+ /**
183
+ * Mettre à jour l'image de profil : Permet de mettre à jour l'image de profil d'un utilisateur ou d'une entité.
184
+ * Constant : PROFIL_IMAGE
185
+ */
186
+ async updateImageProfil(image) {
187
+ image = await this.validateImage(image);
188
+ const data = { pathParams: { folder: this.getEntityType(), ownerId: this.id }, profil_avatar: image };
189
+ return this.callIsConnected(() => this.endpointApi.profilImage(data));
190
+ }
191
+
81
192
  /**
82
193
  * Récupérer les actualités : Récupère la liste d’actualités selon plusieurs critères.
83
194
  * Constant : GET_NEWS
@@ -92,36 +203,27 @@ export class Organization {
92
203
  */
93
204
  async getNews(data = {}) {
94
205
  data.pathParams = { type: this.getEntityType(), id: this.id };
95
- return this._getNews(data);
206
+ const arrayObjetNews = await this.endpointApi.getNews(data);
207
+ if(!Array.isArray(arrayObjetNews)){
208
+ throw new ApiResponseError("Erreur lors de la récupération des actualités.", 500, arrayObjetNews);
209
+ }
210
+ const rawNewsList = arrayObjetNews.map((newsData) =>
211
+ News.fromServerData(newsData, this, { User, EndpointApi: this.deps.EndpointApi })
212
+ );
213
+ return this._createFilteredProxy(rawNewsList);
96
214
  }
97
215
 
98
- /**
99
- * Ajouter une actualité : Ajoute une nouvelle actualité.
100
- * Constant : ADD_NEWS
101
- * @param {Object} data - Les données à envoyer.
102
- * @param {string} data.text - Contenu de l’actualité
103
- * @param {string} data.scope - Portée de l'actualité (ex: public, privé...) (default: "public")
104
- * @param {boolean} data.markdownActive - Markdown activé (true/false) (default: true)
105
- * @param {string} data.type - Type de l'objet, toujours 'news'. (default: "news")
106
- * @param {boolean} data.json - Indique que la réponse est au format JSON. (default: true)
107
- * @param {array | string} data.tags - Tags : "" pour effacer tous les tags, ou tableau de mots-clés.
108
- * @param {object} data.mediaImg - Optionnel. Informations sur les images associées à la news.
109
- * @param {number} data.mediaImg.countImages - Nombre d'images.
110
- * @param {Array<string>} data.mediaImg.images - Liste des identifiants ou chemins d'images.
111
- * @param {object} data.mediaFile - Optionnel. Informations sur les fichiers associés à la news.
112
- * @param {number} data.mediaFile.countFiles - Nombre de fichiers.
113
- * @param {Array<string>} data.mediaFile.files - Liste des identifiants ou chemins de fichiers.
114
- * @param {object} data.mentions - Liste des mentions sous forme d'objet avec des clés dynamiques représentant l'indice de la mention.
115
- * @param {Object.<string, object>} data.mentions - Objet dont les clés keys matching ^[0-9]+$
116
- * @returns {Promise<Object>} - Les données de réponse.
117
- * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
118
- * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
119
- * @throws {Error} - En cas d'erreur inattendue.
120
- */
121
- async addNews(data = {}) {
122
- data.parentId = this.id;
123
- data.parentType = this.getEntityType();
124
- return this.callIsConnected(() => this._addNews(data));
216
+ async news(newsData) {
217
+ try {
218
+ const news = new News(this, newsData, { User, EndpointApi : this.deps.EndpointApi });
219
+ if (newsData.id) {
220
+ await news.get();
221
+ }
222
+ return news;
223
+ } catch (error) {
224
+ console.error("[Api.project.news] Erreur lors de la création d'une instance news :", error.message);
225
+ throw error;
226
+ }
125
227
  }
126
228
 
127
229
  }
@@ -1,6 +1,9 @@
1
- import { EntityMixin } from "./EntityMixin.js";
2
- import { NewsMixin } from "./NewsMixin.js";
3
- import { UtilMixin } from "./UtilMixin.js";
1
+ import { ApiResponseError } from "../error.js";
2
+ import { News } from "./News.js";
3
+ import { User } from "./User.js";
4
+ import { EntityMixin } from "../mixin/EntityMixin.js";
5
+ import { NewsMixin } from "../mixin/NewsMixin.js";
6
+ import { UtilMixin } from "../mixin/UtilMixin.js";
4
7
 
5
8
  // Project.js
6
9
  export class Project {
@@ -13,13 +16,29 @@ export class Project {
13
16
  * Crée une instance de Project.
14
17
  * @param {ApiClient} apiClient - L'instance d'ApiClient.
15
18
  * @param {Object} identifier - Objet contenant { id } ou { slug }.
19
+ * @param {Object} [deps={}] - Dépendances injectées (ex: User).
20
+ * @param {EndpointApi} deps.EndpointApi - Classe EndpointApi pour éviter les dépendances circulaires.
16
21
  */
17
22
 
18
- constructor(apiClient, { id, slug } = {}) {
23
+ constructor(apiClient, { id, slug } = {}, deps = {}) {
24
+ if(!deps.EndpointApi){
25
+ throw new Error("EndpointApi class must be injected to avoid circular dependency.");
26
+ }
19
27
  if (!id && !slug) {
20
- throw new Error("Vous devez fournir un id ou un slug pour créer un User.");
28
+ throw new Error("Vous devez fournir un id ou un slug pour créer une instance Project.");
21
29
  }
22
30
  this.apiClient = apiClient;
31
+ this.deps = deps;
32
+
33
+ // Gérer les deux cas : fonction constructeur ou instance
34
+ if (typeof deps.EndpointApi === "function") {
35
+ this.endpointApi = new deps.EndpointApi(this.apiClient);
36
+ } else if (typeof deps.EndpointApi === "object") {
37
+ this.endpointApi = deps.EndpointApi;
38
+ } else {
39
+ throw new Error("deps.EndpointApi doit être une classe ou une instance valide.");
40
+ }
41
+
23
42
  this.#id = id || null;
24
43
  this.#slug = slug || null;
25
44
  }
@@ -78,6 +97,99 @@ export class Project {
78
97
  });
79
98
  }
80
99
 
100
+ /**
101
+ * Mettre à jour les paramètres d'un élément : Mise à jour des paramètres spécifiques d'un élément.
102
+ * Constant : UPDATE_SETTINGS
103
+ * @param {Object} data - Les données à envoyer.
104
+ * @param {string} data.type - data.type
105
+ * @param {undefined} data.value - data.value
106
+ * @returns {Promise<Object>} - Les données de réponse.
107
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
108
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
109
+ * @throws {Error} - En cas d'erreur inattendue.
110
+ */
111
+ async updateSettings(data = {}) {
112
+ data.idEntity = this.id;
113
+ data.typeEntity = this.getEntityType();
114
+ return this.callIsConnected(() => this.endpointApi.updateSettings(data));
115
+ }
116
+
117
+ /**
118
+ * Mettre à jour la description d'un élément : Permet de mettre à jour la description courte et complète d'un élément.
119
+ * Constant : UPDATE_BLOCK_DESCRIPTION
120
+ * @param {Object} data - Les données à envoyer.
121
+ * @param {string} data.descMentions - Mentions dans la description (default: "")
122
+ * @param {string} data.shortDescription - Courte description
123
+ * @param {string} data.description - Description complète
124
+ * @returns {Promise<Object>} - Les données de réponse.
125
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
126
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
127
+ * @throws {Error} - En cas d'erreur inattendue.
128
+ */
129
+ async updateDescription(data = {}) {
130
+ data.typeElement = this.getEntityType();
131
+ data.id = this.id;
132
+ return this.callIsConnected(() => this.endpointApi.updateBlockDescription(data));
133
+ }
134
+
135
+
136
+ /**
137
+ * Mettre à jour les informations d'un élément : Permet de mettre à jour les informations générales d'un élément (nom, contacts, etc.).
138
+ * Constant : UPDATE_BLOCK_INFO
139
+ */
140
+ async updateInfo(data = {}) {
141
+ data.typeElement = this.getEntityType();
142
+ data.id = this.id;
143
+ return this.callIsConnected(() => this.endpointApi.updateBlockInfo(data));
144
+ }
145
+
146
+ /**
147
+ * Mettre à jour les réseaux sociaux d'un élément : Permet de mettre à jour les liens vers les réseaux sociaux d'un élément.
148
+ * Constant : UPDATE_BLOCK_SOCIAL
149
+ */
150
+ async updateSocial(data = {}) {
151
+ data.typeElement = this.getEntityType();
152
+ data.id = this.id;
153
+ return this.callIsConnected(() => this.endpointApi.updateBlockSocial(data));
154
+ }
155
+
156
+ /**
157
+ * Mettre à jour les localités d'un élément : Permet de mettre à jour l'adresse et les informations géographiques d'un élément.
158
+ * Constant : UPDATE_BLOCK_LOCALITY
159
+ */
160
+ async updateLocality(data = {}) {
161
+ data.typeElement = this.getEntityType();
162
+ data.id = this.id;
163
+ return this.callIsConnected(() => this.endpointApi.updateBlockLocality(data));
164
+ }
165
+
166
+ /**
167
+ * Mettre à jour le slug d'un élément : Permet de mettre à jour le slug pour une URL simplifiée.
168
+ * Constant : UPDATE_BLOCK_SLUG
169
+ */
170
+ async updateSlug(slug) {
171
+ try {
172
+ await this.endpointApi.check({ slug });
173
+ } catch (error) {
174
+ if(error instanceof ApiResponseError) {
175
+ throw new ApiResponseError("Erreur lors de la vérification du slug.", error.status, error.data);
176
+ }
177
+ throw error;
178
+ }
179
+ const data = { typeElement: this.getEntityType(), id: this.id, slug };
180
+ return this.callIsConnected(() => this.endpointApi.updateBlockSlug(data));
181
+ }
182
+
183
+ /**
184
+ * Mettre à jour l'image de profil : Permet de mettre à jour l'image de profil d'un utilisateur ou d'une entité.
185
+ * Constant : PROFIL_IMAGE
186
+ */
187
+ async updateImageProfil(image) {
188
+ image = await this.validateImage(image);
189
+ const data = { pathParams: { folder: this.getEntityType(), ownerId: this.id }, profil_avatar: image };
190
+ return this.callIsConnected(() => this.endpointApi.profilImage(data));
191
+ }
192
+
81
193
  /**
82
194
  * Récupérer les actualités : Récupère la liste d’actualités selon plusieurs critères.
83
195
  * Constant : GET_NEWS
@@ -92,36 +204,27 @@ export class Project {
92
204
  */
93
205
  async getNews(data = {}) {
94
206
  data.pathParams = { type: this.getEntityType(), id: this.id };
95
- return this._getNews(data);
207
+ const arrayObjetNews = await this.endpointApi.getNews(data);
208
+ if(!Array.isArray(arrayObjetNews)){
209
+ throw new ApiResponseError("Erreur lors de la récupération des actualités.", 500, arrayObjetNews);
210
+ }
211
+ const rawNewsList = arrayObjetNews.map((newsData) =>
212
+ News.fromServerData(newsData, this, { User, EndpointApi: this.deps.EndpointApi })
213
+ );
214
+ return this._createFilteredProxy(rawNewsList);
96
215
  }
97
216
 
98
- /**
99
- * Ajouter une actualité : Ajoute une nouvelle actualité.
100
- * Constant : ADD_NEWS
101
- * @param {Object} data - Les données à envoyer.
102
- * @param {string} data.text - Contenu de l’actualité
103
- * @param {string} data.scope - Portée de l'actualité (ex: public, privé...) (default: "public")
104
- * @param {boolean} data.markdownActive - Markdown activé (true/false) (default: true)
105
- * @param {string} data.type - Type de l'objet, toujours 'news'. (default: "news")
106
- * @param {boolean} data.json - Indique que la réponse est au format JSON. (default: true)
107
- * @param {array | string} data.tags - Tags : "" pour effacer tous les tags, ou tableau de mots-clés.
108
- * @param {object} data.mediaImg - Optionnel. Informations sur les images associées à la news.
109
- * @param {number} data.mediaImg.countImages - Nombre d'images.
110
- * @param {Array<string>} data.mediaImg.images - Liste des identifiants ou chemins d'images.
111
- * @param {object} data.mediaFile - Optionnel. Informations sur les fichiers associés à la news.
112
- * @param {number} data.mediaFile.countFiles - Nombre de fichiers.
113
- * @param {Array<string>} data.mediaFile.files - Liste des identifiants ou chemins de fichiers.
114
- * @param {object} data.mentions - Liste des mentions sous forme d'objet avec des clés dynamiques représentant l'indice de la mention.
115
- * @param {Object.<string, object>} data.mentions - Objet dont les clés keys matching ^[0-9]+$
116
- * @returns {Promise<Object>} - Les données de réponse.
117
- * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
118
- * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
119
- * @throws {Error} - En cas d'erreur inattendue.
120
- */
121
- async addNews(data = {}) {
122
- data.parentId = this.id;
123
- data.parentType = this.getEntityType();
124
- return this.callIsConnected(() => this._addNews(data));
217
+ async news(newsData) {
218
+ try {
219
+ const news = new News(this, newsData, { User, EndpointApi : this.deps.EndpointApi });
220
+ if (newsData.id) {
221
+ await news.get();
222
+ }
223
+ return news;
224
+ } catch (error) {
225
+ console.error("[Api.project.news] Erreur lors de la création d'une instance news :", error.message);
226
+ throw error;
227
+ }
125
228
  }
126
229
 
127
230
  }