@communecter/cocolight-api-client 1.0.8 → 1.0.10
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/dist/22.cocolight-api-client.mjs.js +1 -0
- package/dist/320.cocolight-api-client.browser.js +1 -0
- package/dist/931.cocolight-api-client.browser.js +1 -0
- package/dist/931.cocolight-api-client.cjs +1 -0
- package/dist/cocolight-api-client.browser.js +3 -3
- package/dist/cocolight-api-client.cjs +1 -2
- package/dist/cocolight-api-client.mjs.js +1 -2
- package/package.json +6 -3
- package/src/Api.js +36 -19
- package/src/ApiClient.js +56 -11
- package/src/api/EndpointApi.js +1534 -0
- package/src/api/News.js +327 -0
- package/src/api/Organization.js +268 -84
- package/src/api/Project.js +287 -93
- package/src/api/User.js +397 -87
- package/src/api/UserApi.js +5 -1
- package/src/endpoints.module.js +2 -2
- package/src/mixin/DraftStateMixin.js +176 -0
- package/src/mixin/EntityMixin.js +109 -0
- package/src/mixin/MutualEntityMixin.js +48 -0
- package/src/mixin/NewsMixin.js +42 -0
- package/src/mixin/UserMixin.js +8 -0
- package/src/mixin/UtilMixin.js +294 -0
- package/src/utils/stream-utils.node.js +10 -0
- package/dist/cocolight-api-client.cjs.LICENSE.txt +0 -1
- package/dist/cocolight-api-client.mjs.js.LICENSE.txt +0 -1
- package/src/api/EntityMixin.js +0 -249
- package/src/api/NewsMixin.js +0 -168
- package/src/api/UserMixin.js +0 -59
- package/src/api/UtilMixin.js +0 -82
package/src/api/News.js
ADDED
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { ApiError } from "../error.js";
|
|
2
|
+
import { DraftStateMixin } from "../mixin/DraftStateMixin.js";
|
|
3
|
+
import { UtilMixin } from "../mixin/UtilMixin.js";
|
|
4
|
+
|
|
5
|
+
// News.js
|
|
6
|
+
export class News {
|
|
7
|
+
#draftData = {};
|
|
8
|
+
#initialDraftData = {};
|
|
9
|
+
#serverData = null;
|
|
10
|
+
|
|
11
|
+
static entityType = "news";
|
|
12
|
+
|
|
13
|
+
static SCHEMA_CONSTANTS = [
|
|
14
|
+
"ADD_NEWS"
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Crée une instance de News.
|
|
19
|
+
* @param {(Organization|Project|User)} parent - L'instance de l'element parent (ex: Organization, Project, User).
|
|
20
|
+
* @param {Object} data - Objet contenant { id }
|
|
21
|
+
* @param {Object} deps - Dépendances injectées (ex: User).
|
|
22
|
+
* @param {EndpointApi} deps.EndpointApi - Classe EndpointApi pour éviter les dépendances circulaires.
|
|
23
|
+
* @param {User} deps.User - Classe User pour éviter les dépendances circulaires.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
constructor(parent, data = {}, deps = {}) {
|
|
27
|
+
this.__entityTag = "News";
|
|
28
|
+
|
|
29
|
+
if (!deps.EndpointApi) throw new ApiError("EndpointApi class must be injected to avoid circular dependency.");
|
|
30
|
+
if (!deps.User) throw new ApiError("User class must be injected.");
|
|
31
|
+
|
|
32
|
+
if (!parent) throw new ApiError("Parent is required.");
|
|
33
|
+
this.deps = deps;
|
|
34
|
+
this.EndpointApiClass = deps.EndpointApi;
|
|
35
|
+
|
|
36
|
+
if (parent?.__entityTag === "User" || parent?.__entityTag === "Organization" || parent?.__entityTag === "Project") {
|
|
37
|
+
this.apiClient = parent.apiClient;
|
|
38
|
+
this.parent = parent;
|
|
39
|
+
} else {
|
|
40
|
+
throw new ApiError("Invalid parent for News.");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
this.endpointApi = typeof deps.EndpointApi === "function"
|
|
44
|
+
? new deps.EndpointApi(this.apiClient)
|
|
45
|
+
: (typeof deps.EndpointApi === "object"
|
|
46
|
+
? deps.EndpointApi
|
|
47
|
+
: (() => { throw new ApiError("deps.EndpointApi must be a class or instance."); })());
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
this.#serverData = null;
|
|
51
|
+
|
|
52
|
+
const { draft, proxy } = this.buildDraftAndProxy({
|
|
53
|
+
data: { ...data, ...this.defaultFields },
|
|
54
|
+
serverData: this.#serverData,
|
|
55
|
+
constant: News.SCHEMA_CONSTANTS,
|
|
56
|
+
apiClient: this.apiClient,
|
|
57
|
+
transforms: this.transforms,
|
|
58
|
+
removeFields: this.removeFields
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
this.#initialDraftData = JSON.parse(JSON.stringify(draft)); // snapshot propre
|
|
62
|
+
this.#draftData = draft;
|
|
63
|
+
this.data = proxy;
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
// Getters en lecture seule pour chaque propriété
|
|
69
|
+
get id() {
|
|
70
|
+
return this.#draftData.id || null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get isConnected() {
|
|
74
|
+
return this.apiClient.isConnected;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get draftData() {
|
|
78
|
+
return this.#draftData;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get initialDraftData() {
|
|
82
|
+
return this.#initialDraftData;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get serverData() {
|
|
86
|
+
return this.#serverData;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get userId() {
|
|
90
|
+
return this.apiClient.userId;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get isMe() {
|
|
94
|
+
return this.isConnected && this.userId === this.parent.id;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_setData(newData) {
|
|
98
|
+
this.#serverData = { ...newData };
|
|
99
|
+
|
|
100
|
+
const { draft, proxy } = this.buildDraftAndProxy({
|
|
101
|
+
data: { ...newData, ...this.defaultFields },
|
|
102
|
+
serverData: this.#serverData,
|
|
103
|
+
constant: News.SCHEMA_CONSTANTS,
|
|
104
|
+
apiClient: this.apiClient,
|
|
105
|
+
transforms: this.transforms,
|
|
106
|
+
removeFields: this.removeFields
|
|
107
|
+
});
|
|
108
|
+
this.#initialDraftData = JSON.parse(JSON.stringify(draft));
|
|
109
|
+
this.#draftData = draft;
|
|
110
|
+
this.data = proxy;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
getEntityType() {
|
|
114
|
+
return News.entityType;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static fromServerData(data, parent, deps) {
|
|
118
|
+
const instance = new News(parent, {}, deps);
|
|
119
|
+
instance.#serverData = { ...data };
|
|
120
|
+
|
|
121
|
+
const { draft, proxy } = instance.buildDraftAndProxy({
|
|
122
|
+
data: { ...data, ...instance.defaultFields },
|
|
123
|
+
serverData: instance.#serverData,
|
|
124
|
+
constant: News.SCHEMA_CONSTANTS,
|
|
125
|
+
apiClient: instance.apiClient,
|
|
126
|
+
transforms: instance.transforms,
|
|
127
|
+
removeFields: instance.removeFields
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
instance.#draftData = draft;
|
|
131
|
+
instance.data = proxy;
|
|
132
|
+
|
|
133
|
+
return instance;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async refresh() {
|
|
137
|
+
if (!this.id) throw new ApiError("Impossible de rafraîchir sans ID.");
|
|
138
|
+
return this.get();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Récupérer des actualités par IDs : Récupère des actualités à partir d’une liste d’identifiants.
|
|
143
|
+
* Constant : GET_NEWS_BY_ID
|
|
144
|
+
*/
|
|
145
|
+
async get() {
|
|
146
|
+
if (!this.id) throw new ApiError("Impossible de rafraîchir sans ID.");
|
|
147
|
+
|
|
148
|
+
const newsArray = await this.callIsConnected(() =>
|
|
149
|
+
this.endpointApi.getNewsById({ ids: [this.id] })
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
if (newsArray && Array.isArray(newsArray) && newsArray.length === 1) {
|
|
153
|
+
const data = newsArray[0];
|
|
154
|
+
this.#serverData = { ...data };
|
|
155
|
+
|
|
156
|
+
this._setData(data);
|
|
157
|
+
|
|
158
|
+
return this.#serverData;
|
|
159
|
+
}
|
|
160
|
+
throw new ApiError(`Aucune actualité trouvée pour l'ID ${this.id}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Ajouter une actualité : Ajoute une nouvelle actualité.
|
|
166
|
+
* Constant : ADD_NEWS | UPDATE_NEWS
|
|
167
|
+
*/
|
|
168
|
+
async save() {
|
|
169
|
+
|
|
170
|
+
if(!this.isConnected){
|
|
171
|
+
throw new ApiError("Impossible de sauvegarder sans être connecté.");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// si le texte est vide, on met un espace pour que le champ soit pris en compte car sur le serveur
|
|
175
|
+
// il y a une vérification de la taille du texte je pense
|
|
176
|
+
if(this.#draftData?.text === ""){
|
|
177
|
+
this.#draftData.text = " ";
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const payload = { ...this.#draftData };
|
|
181
|
+
payload.parentId = this.parent.id;
|
|
182
|
+
payload.parentType = this.parent.getEntityType();
|
|
183
|
+
|
|
184
|
+
if (!this.id) {
|
|
185
|
+
const reponseData = await this.callIsConnected(() => this.endpointApi.addNews(payload));
|
|
186
|
+
this.#draftData.id = reponseData.object.id;
|
|
187
|
+
// TODO : voir si j'ai ce qui faut dans reponseData de ADD_NEWS pour mettre à jour #serverData
|
|
188
|
+
// c'est dans reponseData.object
|
|
189
|
+
if(reponseData?.object){
|
|
190
|
+
this.#serverData = { ...reponseData.object };
|
|
191
|
+
}
|
|
192
|
+
// await this.refresh();
|
|
193
|
+
return reponseData;
|
|
194
|
+
} else {
|
|
195
|
+
if(payload.id){
|
|
196
|
+
delete payload.id;
|
|
197
|
+
}
|
|
198
|
+
const reponseData = await this.callIsConnected(() => this.endpointApi.updateNews({ ...payload, idNews: this.id }));
|
|
199
|
+
// TODO : voir si j'ai ce qui faut dans reponseData de UPDATE_NEWS pour mettre à jour #serverData
|
|
200
|
+
// c'est dans reponseData.object
|
|
201
|
+
if(reponseData?.object){
|
|
202
|
+
this.#serverData = { ...reponseData.object };
|
|
203
|
+
}
|
|
204
|
+
// await this.refresh();
|
|
205
|
+
return reponseData;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
async addMention({ slug, id }) {
|
|
211
|
+
try {
|
|
212
|
+
if (!slug && !id) {
|
|
213
|
+
throw new ApiError("Vous devez fournir un slug ou un id pour ajouter une mention.");
|
|
214
|
+
}
|
|
215
|
+
const userInstance = new this.deps.User(this.apiClient, { id, slug }, { EndpointApi: this.endpointApi });
|
|
216
|
+
const user = userInstance.serverData;
|
|
217
|
+
if (!this.#draftData.mentions) {
|
|
218
|
+
this.#draftData.mentions = [];
|
|
219
|
+
}
|
|
220
|
+
// Vérification si la mention existe déjà
|
|
221
|
+
if (this.#draftData.mentions.find((mention) => mention.id === user.id)) {
|
|
222
|
+
// Si la mention existe déjà, on incrémente le compteur
|
|
223
|
+
this.#draftData.mentions = this.#draftData.mentions.map((mention) => {
|
|
224
|
+
if (mention.id === user.id) {
|
|
225
|
+
mention.count += 1;
|
|
226
|
+
}
|
|
227
|
+
return mention;
|
|
228
|
+
});
|
|
229
|
+
return this.#draftData.mentions;
|
|
230
|
+
}
|
|
231
|
+
const mention = { id: user.id, slug: user.slug, type: userInstance.getEntityType(), name: user.name, value: user.name, count: 1 };
|
|
232
|
+
this.#draftData.mentions.push(mention);
|
|
233
|
+
return this.#draftData.mentions;
|
|
234
|
+
} catch (error) {
|
|
235
|
+
this.apiClient._logger.error("Erreur lors de l'ajout de la mention :", error);
|
|
236
|
+
throw error;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Ajouter une image à une actualité : Ajoute une images à une actualité.
|
|
244
|
+
* Constant : ADD_IMAGE_NEWS
|
|
245
|
+
*/
|
|
246
|
+
async addImage(image) {
|
|
247
|
+
image = await this.validateImage(image);
|
|
248
|
+
const data = { pathParams: { folder: this.parent.getEntityType(), ownerId: this.parent.id }, newsImage: image };
|
|
249
|
+
const dataImage = await this.callIsConnected(() => this.endpointApi.addImageNews(data));
|
|
250
|
+
if (this.#draftData.mediaImg) {
|
|
251
|
+
this.#draftData.mediaImg.countImages = this.#draftData.mediaImg.countImages + 1;
|
|
252
|
+
this.#draftData.mediaImg.images.push(dataImage.id);
|
|
253
|
+
} else {
|
|
254
|
+
this.#draftData.mediaImg = { countImages: 1, images: [dataImage.id] };
|
|
255
|
+
}
|
|
256
|
+
return dataImage;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Ajouter un fichier à une actualité : Ajoute un fichier à une actualité.
|
|
261
|
+
* Constant : ADD_FILE_NEWS
|
|
262
|
+
*/
|
|
263
|
+
async addFile(file) {
|
|
264
|
+
file = await this.validateFile(file);
|
|
265
|
+
const data = { pathParams: { folder: this.parent.getEntityType(), ownerId: this.parent.id }, newsFile: file };
|
|
266
|
+
const dataFile = await this.callIsConnected(() =>this.endpointApi.addFileNews(data));
|
|
267
|
+
if (this.#draftData.mediaFile) {
|
|
268
|
+
this.#draftData.mediaFile.countFiles = this.#draftData.mediaFile.countFiles + 1;
|
|
269
|
+
this.#draftData.mediaFile.files.push(dataFile);
|
|
270
|
+
} else {
|
|
271
|
+
this.#draftData.mediaFile = { countFiles: 1, files: [dataFile] };
|
|
272
|
+
}
|
|
273
|
+
return dataFile;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Supprimer une actualité : Supprime une actualité existante.
|
|
278
|
+
* Constant : DELETE_NEWS
|
|
279
|
+
*/
|
|
280
|
+
async delete() {
|
|
281
|
+
if(!this.id) {
|
|
282
|
+
throw new ApiError("Vous devez fournir un id pour supprimer une news.");
|
|
283
|
+
}
|
|
284
|
+
const data = { pathParams: { id: this.id } };
|
|
285
|
+
await this.callIsConnected(() => this.endpointApi.deleteNews(data));
|
|
286
|
+
this.#draftData = {};
|
|
287
|
+
this.#serverData = null;
|
|
288
|
+
this.#draftData.id = null;
|
|
289
|
+
this._isDeleted = true;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
_updateInitialDraftSnapshot() {
|
|
293
|
+
this.#initialDraftData = JSON.parse(JSON.stringify(this.#draftData));
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
hasChanges() {
|
|
297
|
+
return JSON.stringify(this.#draftData) !== JSON.stringify(this.#initialDraftData);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
defaultFields = {
|
|
301
|
+
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
removeFields = [
|
|
305
|
+
|
|
306
|
+
];
|
|
307
|
+
|
|
308
|
+
transforms = {
|
|
309
|
+
scope: val => val?.type,
|
|
310
|
+
mentions: val =>
|
|
311
|
+
Array.isArray(val)
|
|
312
|
+
? val.map(m => ({ ...m, count: parseInt(m.count) }))
|
|
313
|
+
: [],
|
|
314
|
+
mediaImg: val => {
|
|
315
|
+
const images = val?.images?.map(img => img.id).filter(Boolean) || [];
|
|
316
|
+
return images.length > 0 ? { countImages: images.length, images } : undefined;
|
|
317
|
+
},
|
|
318
|
+
mediaFile: val => {
|
|
319
|
+
const files = val?.files?.map(f => f.id).filter(Boolean) || [];
|
|
320
|
+
return files.length > 0 ? { countFiles: files.length, files } : undefined;
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Incorporation du mixin dans Organization
|
|
327
|
+
Object.assign(News.prototype, UtilMixin, DraftStateMixin);
|