@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/User.js
CHANGED
|
@@ -1,66 +1,128 @@
|
|
|
1
|
-
import { ApiResponseError } from "../error.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { UserMixin } from "
|
|
5
|
-
import { UtilMixin } from "
|
|
1
|
+
import { ApiError, ApiResponseError } from "../error.js";
|
|
2
|
+
import { DraftStateMixin } from "../mixin/DraftStateMixin.js";
|
|
3
|
+
import { MutualEntityMixin } from "../mixin/MutualEntityMixin.js";
|
|
4
|
+
import { UserMixin } from "../mixin/UserMixin.js";
|
|
5
|
+
import { UtilMixin } from "../mixin/UtilMixin.js";
|
|
6
6
|
|
|
7
7
|
// User.js
|
|
8
8
|
export class User {
|
|
9
|
-
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
|
|
9
|
+
#draftData = {};
|
|
10
|
+
#initialDraftData = {};
|
|
11
|
+
#serverData = null;
|
|
12
|
+
|
|
13
|
+
static entityType = "citoyens";
|
|
14
|
+
|
|
15
|
+
static SCHEMA_CONSTANTS = [
|
|
16
|
+
"UPDATE_BLOCK_DESCRIPTION",
|
|
17
|
+
"UPDATE_BLOCK_INFO",
|
|
18
|
+
"UPDATE_BLOCK_SOCIAL",
|
|
19
|
+
"UPDATE_BLOCK_LOCALITY",
|
|
20
|
+
"UPDATE_BLOCK_SLUG",
|
|
21
|
+
"PROFIL_IMAGE"
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
static UPDATE_BLOCKS = new Map([
|
|
25
|
+
["UPDATE_BLOCK_DESCRIPTION", "updateDescription"],
|
|
26
|
+
["UPDATE_BLOCK_SOCIAL", "updateSocial"],
|
|
27
|
+
["UPDATE_BLOCK_LOCALITY", "updateLocality"],
|
|
28
|
+
["UPDATE_BLOCK_INFO", "updateInfo"],
|
|
29
|
+
["UPDATE_BLOCK_SLUG", "updateSlug"],
|
|
30
|
+
["PROFIL_IMAGE", "updateImageProfil"]
|
|
31
|
+
]);
|
|
13
32
|
|
|
14
33
|
/**
|
|
15
34
|
* Crée une instance de User.
|
|
16
|
-
*
|
|
17
|
-
* @param {
|
|
18
|
-
* @param {Object}
|
|
35
|
+
*
|
|
36
|
+
* @param {ApiClient} apiClient - Le client API connecté.
|
|
37
|
+
* @param {Object} data - Données initiales (peuvent inclure `id`, `slug`, etc.).
|
|
38
|
+
* @param {string} [data.id] - ID de l'utilisateur.
|
|
39
|
+
* @param {string} [data.slug] - Slug de l'utilisateur.
|
|
40
|
+
* @param {Object} deps - Dépendances injectées.
|
|
41
|
+
* @param {function|object} deps.EndpointApi - Classe ou instance de EndpointApi.
|
|
42
|
+
* @param {function} deps.Organization - Classe Organization.
|
|
43
|
+
* @param {function} deps.Project - Classe Project.
|
|
44
|
+
* @param {function} deps.News - Classe News.
|
|
45
|
+
*
|
|
46
|
+
* @throws {ApiError} - Si des dépendances nécessaires sont manquantes ou invalides.
|
|
19
47
|
*/
|
|
20
48
|
|
|
21
|
-
constructor(apiClient,
|
|
22
|
-
|
|
23
|
-
|
|
49
|
+
constructor(apiClient, data = {}, deps = {}) {
|
|
50
|
+
this.__entityTag = "User";
|
|
51
|
+
|
|
52
|
+
if(!deps.EndpointApi){
|
|
53
|
+
throw new ApiError("EndpointApi class must be injected to avoid circular dependency.");
|
|
24
54
|
}
|
|
55
|
+
if (!data?.id && !data?.slug) {
|
|
56
|
+
throw new ApiError("Vous devez fournir un id ou un slug pour créer un User.");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!deps.Organization) throw new ApiError("Organization class must be injected.");
|
|
60
|
+
if (!deps.Project) throw new ApiError("Project class must be injected.");
|
|
61
|
+
if (!deps.News) throw new ApiError("News class must be injected.");
|
|
62
|
+
|
|
25
63
|
this.apiClient = apiClient;
|
|
26
|
-
|
|
27
|
-
this
|
|
28
|
-
|
|
64
|
+
|
|
65
|
+
this.deps = deps;
|
|
66
|
+
|
|
67
|
+
// Gérer les deux cas : fonction constructeur ou instance
|
|
68
|
+
if (typeof deps.EndpointApi === "function") {
|
|
69
|
+
this.endpointApi = new deps.EndpointApi(this.apiClient);
|
|
70
|
+
} else if (typeof deps.EndpointApi === "object") {
|
|
71
|
+
this.endpointApi = deps.EndpointApi;
|
|
72
|
+
} else {
|
|
73
|
+
throw new ApiError("deps.EndpointApi doit être une classe ou une instance valide.");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
this.#serverData = null;
|
|
77
|
+
|
|
78
|
+
const { draft, proxy } = this.buildDraftAndProxy({
|
|
79
|
+
data: { ...data, ...this.defaultFields },
|
|
80
|
+
serverData: this.#serverData,
|
|
81
|
+
constant: User.SCHEMA_CONSTANTS,
|
|
82
|
+
apiClient: this.apiClient,
|
|
83
|
+
transforms: this.transforms,
|
|
84
|
+
removeFields: this.removeFields
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
this.#initialDraftData = JSON.parse(JSON.stringify(draft)); // snapshot propre
|
|
88
|
+
this.#draftData = draft;
|
|
89
|
+
this.data = proxy;
|
|
29
90
|
}
|
|
30
|
-
|
|
31
|
-
// Getters en lecture seule pour chaque propriété
|
|
91
|
+
|
|
32
92
|
get id() {
|
|
33
|
-
return this.#id;
|
|
93
|
+
return this.#draftData.id || null;
|
|
34
94
|
}
|
|
35
95
|
|
|
36
96
|
_id(newId) {
|
|
37
|
-
this.#id = newId;
|
|
97
|
+
this.#draftData.id = newId;
|
|
38
98
|
}
|
|
39
|
-
|
|
99
|
+
|
|
40
100
|
get slug() {
|
|
41
|
-
return this.#slug;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
_slug(newSlug) {
|
|
45
|
-
this.#slug = newSlug;
|
|
101
|
+
return this.#draftData.slug || null;
|
|
46
102
|
}
|
|
47
103
|
|
|
48
104
|
get isConnected() {
|
|
49
105
|
return this.apiClient.isConnected;
|
|
50
106
|
}
|
|
51
107
|
|
|
52
|
-
// Getter pour accéder aux données
|
|
53
|
-
get data() {
|
|
54
|
-
return this.#data;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Méthode interne qui permet de mettre à jour les données
|
|
58
108
|
_setData(newData) {
|
|
59
|
-
this.#
|
|
109
|
+
this.#serverData = { ...newData };
|
|
110
|
+
|
|
111
|
+
const { draft, proxy } = this.buildDraftAndProxy({
|
|
112
|
+
data: { ...newData, ...this.defaultFields },
|
|
113
|
+
serverData: this.#serverData,
|
|
114
|
+
constant: User.SCHEMA_CONSTANTS,
|
|
115
|
+
apiClient: this.apiClient,
|
|
116
|
+
transforms: this.transforms,
|
|
117
|
+
removeFields: this.removeFields
|
|
118
|
+
});
|
|
119
|
+
this.#initialDraftData = JSON.parse(JSON.stringify(draft));
|
|
120
|
+
this.#draftData = draft;
|
|
121
|
+
this.data = proxy;
|
|
60
122
|
}
|
|
61
123
|
|
|
62
124
|
getEntityType() {
|
|
63
|
-
return
|
|
125
|
+
return User.entityType;
|
|
64
126
|
}
|
|
65
127
|
|
|
66
128
|
get userId() {
|
|
@@ -71,6 +133,23 @@ export class User {
|
|
|
71
133
|
return this.isConnected && this.userId === this.id;
|
|
72
134
|
}
|
|
73
135
|
|
|
136
|
+
get draftData() {
|
|
137
|
+
return this.#draftData;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
get initialDraftData() {
|
|
141
|
+
return this.#initialDraftData;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
get serverData() {
|
|
145
|
+
return this.#serverData;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async refresh() {
|
|
149
|
+
if (!this.id) throw new ApiError("Impossible de rafraîchir sans ID.");
|
|
150
|
+
return this.get();
|
|
151
|
+
}
|
|
152
|
+
|
|
74
153
|
/**
|
|
75
154
|
* Récupère le profil complet de l'utilisateur.
|
|
76
155
|
* Si l'utilisateur est connecté, on appelle le endpoint ME_INFO_URL,
|
|
@@ -78,13 +157,15 @@ export class User {
|
|
|
78
157
|
*
|
|
79
158
|
* @returns {Promise<Object>} Le profil complet.
|
|
80
159
|
*/
|
|
81
|
-
async
|
|
160
|
+
async get() {
|
|
82
161
|
return this.apiClient.safeCall(async () => {
|
|
83
162
|
if (this.isMe) {
|
|
84
|
-
const data = await this.
|
|
163
|
+
const data = await this.endpointApi.meInfoUrl();
|
|
164
|
+
this._setData(data);
|
|
85
165
|
return data;
|
|
86
166
|
} else {
|
|
87
167
|
const data = await this.getPublicProfile();
|
|
168
|
+
this._setData(data);
|
|
88
169
|
return data;
|
|
89
170
|
}
|
|
90
171
|
});
|
|
@@ -95,7 +176,7 @@ export class User {
|
|
|
95
176
|
* Constant : CHANGE_PASSWORD
|
|
96
177
|
*/
|
|
97
178
|
async changePassword(data = {}) {
|
|
98
|
-
return this.callIsMe(() => this.
|
|
179
|
+
return this.callIsMe(() => this.endpointApi.changePassword(data));
|
|
99
180
|
}
|
|
100
181
|
|
|
101
182
|
/**
|
|
@@ -103,15 +184,77 @@ export class User {
|
|
|
103
184
|
* Constant : DELETE_ACCOUNT
|
|
104
185
|
*/
|
|
105
186
|
async delete(data = {}) {
|
|
106
|
-
return this.callIsMe(() => this.
|
|
187
|
+
return this.callIsMe(() => this.endpointApi.deleteAccount(data));
|
|
107
188
|
}
|
|
108
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Sauvegarde les modifications de l'utilisateur en appelant les endpoints correspondants.
|
|
192
|
+
* Seul l'utilisateur connecté peut se modifier lui-même.
|
|
193
|
+
*
|
|
194
|
+
* @returns {Promise<Object>} - Données serveur mises à jour si applicable.
|
|
195
|
+
* @throws {ApiError} - Si l'utilisateur n'est pas autorisé.
|
|
196
|
+
*/
|
|
197
|
+
async save() {
|
|
198
|
+
|
|
199
|
+
if(!this.isMe){
|
|
200
|
+
throw new ApiError("Vous devez être connecté et être l'utilisateur pour sauvegarder.");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const payload = { ...this.#draftData };
|
|
204
|
+
|
|
205
|
+
if (this.id) {
|
|
206
|
+
const hasChanged = await this._update(payload);
|
|
207
|
+
if (hasChanged) {
|
|
208
|
+
// this._updateInitialDraftSnapshot();
|
|
209
|
+
await this.refresh();
|
|
210
|
+
}
|
|
211
|
+
return this.#serverData;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Met à jour les blocs modifiés de l'utilisateur via les constantes de schéma définies.
|
|
218
|
+
*
|
|
219
|
+
* @param {Object} payload - Données courantes à comparer et envoyer.
|
|
220
|
+
* @returns {Promise<boolean>} - Indique s'il y a eu une modification réelle.
|
|
221
|
+
*/
|
|
222
|
+
async _update(payload){
|
|
223
|
+
if(payload.id){
|
|
224
|
+
delete payload.id;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
let hasChanged = false;
|
|
228
|
+
|
|
229
|
+
// Sinon, on fait les updates en blocs
|
|
230
|
+
for (const [constant, methodName] of User.UPDATE_BLOCKS) {
|
|
231
|
+
const blockData = this.extractChangedFieldsFromSchema(
|
|
232
|
+
this.apiClient,
|
|
233
|
+
constant,
|
|
234
|
+
{ ...payload, ...this.defaultFields},
|
|
235
|
+
() => this.initialDraftData,
|
|
236
|
+
this.removeFields
|
|
237
|
+
);
|
|
238
|
+
if (blockData && Object.keys(blockData).length > 0) {
|
|
239
|
+
await this[methodName](blockData);
|
|
240
|
+
hasChanged = true;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return hasChanged;
|
|
245
|
+
}
|
|
246
|
+
|
|
109
247
|
/**
|
|
110
248
|
* Mettre à jour les paramètres utilisateur : Mise à jour des paramètres spécifiques d'un utilisateur.
|
|
111
249
|
* Constant : UPDATE_SETTINGS
|
|
250
|
+
* @param {Object} data - Données à mettre à jour.
|
|
251
|
+
* @param {"birthDate"|"email"|"locality"|"phone"|"directory"} data.type - Type de paramètre à mettre à jour.
|
|
252
|
+
* @param {"private"|"public"|"mask"} data.value - Nouvelle valeur du paramètre.
|
|
253
|
+
* @returns {Promise<void>} - Résultat de la mise à jour.
|
|
112
254
|
*/
|
|
113
255
|
async updateSettings(data = {}) {
|
|
114
|
-
|
|
256
|
+
await this.callIsMe(() => this.endpointApi.updateSettings(data));
|
|
257
|
+
await this.refresh();
|
|
115
258
|
}
|
|
116
259
|
|
|
117
260
|
/**
|
|
@@ -119,7 +262,7 @@ export class User {
|
|
|
119
262
|
* Constant : UPDATE_BLOCK_DESCRIPTION
|
|
120
263
|
*/
|
|
121
264
|
async updateDescription(data = {}) {
|
|
122
|
-
return this.callIsMe(() => this.
|
|
265
|
+
return this.callIsMe(() => this.endpointApi.updateBlockDescription(data));
|
|
123
266
|
}
|
|
124
267
|
|
|
125
268
|
/**
|
|
@@ -127,7 +270,7 @@ export class User {
|
|
|
127
270
|
* Constant : UPDATE_BLOCK_INFO
|
|
128
271
|
*/
|
|
129
272
|
async updateInfo(data = {}) {
|
|
130
|
-
return this.callIsMe(() => this.
|
|
273
|
+
return this.callIsMe(() => this.endpointApi.updateBlockInfo(data));
|
|
131
274
|
}
|
|
132
275
|
|
|
133
276
|
/**
|
|
@@ -135,7 +278,7 @@ export class User {
|
|
|
135
278
|
* Constant : UPDATE_BLOCK_SOCIAL
|
|
136
279
|
*/
|
|
137
280
|
async updateSocial(data = {}) {
|
|
138
|
-
return this.callIsMe(() => this.
|
|
281
|
+
return this.callIsMe(() => this.endpointApi.updateBlockSocial(data));
|
|
139
282
|
}
|
|
140
283
|
|
|
141
284
|
/**
|
|
@@ -143,36 +286,166 @@ export class User {
|
|
|
143
286
|
* Constant : UPDATE_BLOCK_LOCALITY
|
|
144
287
|
*/
|
|
145
288
|
async updateLocality(data = {}) {
|
|
146
|
-
return this.callIsMe(() => this.
|
|
289
|
+
return this.callIsMe(() => this.endpointApi.updateBlockLocality(data));
|
|
147
290
|
}
|
|
148
291
|
|
|
149
292
|
/**
|
|
150
293
|
* Mettre à jour le slug d'un élément : Permet de mettre à jour le slug pour une URL simplifiée.
|
|
151
294
|
* Constant : UPDATE_BLOCK_SLUG
|
|
152
295
|
*/
|
|
153
|
-
async updateSlug(slug) {
|
|
296
|
+
async updateSlug({ slug }) {
|
|
154
297
|
try {
|
|
155
|
-
await this.
|
|
298
|
+
await this.endpointApi.check({ slug });
|
|
156
299
|
} catch (error) {
|
|
157
300
|
if(error instanceof ApiResponseError) {
|
|
158
301
|
throw new ApiResponseError("Erreur lors de la vérification du slug.", error.status, error.data);
|
|
159
302
|
}
|
|
160
303
|
throw error;
|
|
161
304
|
}
|
|
162
|
-
return this.callIsMe(() => this.
|
|
305
|
+
return this.callIsMe(() => this.endpointApi.updateBlockSlug({ slug }));
|
|
163
306
|
}
|
|
164
307
|
|
|
165
308
|
/**
|
|
166
309
|
* Mettre à jour l'image de profil : Permet de mettre à jour l'image de profil d'un utilisateur ou d'une entité.
|
|
167
310
|
* Constant : PROFIL_IMAGE
|
|
168
311
|
*/
|
|
169
|
-
async updateImageProfil(image) {
|
|
312
|
+
async updateImageProfil({ profil_avatar: image }) {
|
|
170
313
|
image = await this.validateImage(image);
|
|
171
|
-
return this.callIsMe(() => this.
|
|
314
|
+
return this.callIsMe(() => this.endpointApi.profilImage({ profil_avatar: image }));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Récupérer les organisations d'un utilisateur : Récupère la liste des organisations auxquelles l'utilisateur appartient.
|
|
319
|
+
* Constant : GET_ORGANIZATIONS_ADMIN | GET_ORGANIZATIONS_NO_ADMIN
|
|
320
|
+
*/
|
|
321
|
+
async getOrganizations(data = {}) {
|
|
322
|
+
delete data?.pathParams;
|
|
323
|
+
|
|
324
|
+
const fetchFn = this.isMe
|
|
325
|
+
? () => this.callIsMe(() => this.endpointApi.getOrganizationsAdmin(data))
|
|
326
|
+
: () => this.endpointApi.getOrganizationsNoAdmin(data);
|
|
327
|
+
|
|
328
|
+
if (!this.isMe && !data.filters) {
|
|
329
|
+
data.filters = {
|
|
330
|
+
[`links.members.${this.id}`]: { "$exists": true },
|
|
331
|
+
[`links.members.${this.id}.toBeValidated`]: { "$exists": false },
|
|
332
|
+
[`links.members.${this.id}.isInviting`]: { "$exists": false }
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const arrayObjetOrganizations = await fetchFn();
|
|
337
|
+
|
|
338
|
+
if (!Array.isArray(arrayObjetOrganizations.results)) {
|
|
339
|
+
throw new ApiResponseError("Erreur lors de la récupération des organisations.", 500, arrayObjetOrganizations.results);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// nettoyage du count
|
|
343
|
+
delete arrayObjetOrganizations?.count?.spam;
|
|
344
|
+
|
|
345
|
+
// calcul du total
|
|
346
|
+
const totalCount = Object.values(arrayObjetOrganizations.count || {}).reduce((acc, val) => acc + val, 0);
|
|
347
|
+
arrayObjetOrganizations.count.total = totalCount;
|
|
348
|
+
|
|
349
|
+
// transformation des résultats
|
|
350
|
+
const rawOrganizationsList = arrayObjetOrganizations.results.map((orgData) =>
|
|
351
|
+
this.deps.Organization.fromServerData(orgData, this, {
|
|
352
|
+
User,
|
|
353
|
+
Project: this.deps.Project,
|
|
354
|
+
News: this.deps.News,
|
|
355
|
+
EndpointApi: this.deps.EndpointApi
|
|
356
|
+
})
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
return {
|
|
360
|
+
count: arrayObjetOrganizations.count,
|
|
361
|
+
results: rawOrganizationsList
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Crée une instance d'organisation et récupère son profil si nécessaire.
|
|
367
|
+
*
|
|
368
|
+
* @param {Object} organizationData - Les données nécessaires pour initialiser l'organisation.
|
|
369
|
+
* @returns {Promise<Organization>} Une promesse qui résout l'objet Organisation créé.
|
|
370
|
+
* @throws {Error} Si une erreur se produit lors de la création de l'organisation.
|
|
371
|
+
*/
|
|
372
|
+
async organization(organizationData = {}, ) {
|
|
373
|
+
try {
|
|
374
|
+
const organization = new this.deps.Organization(this, organizationData, { User, Project: this.deps.Project, News: this.deps.News, EndpointApi : this.deps.EndpointApi });
|
|
375
|
+
if (organizationData.id || organizationData.slug) {
|
|
376
|
+
await organization.get();
|
|
377
|
+
}
|
|
378
|
+
return organization;
|
|
379
|
+
} catch (error) {
|
|
380
|
+
this.apiClient._logger.error(`[Api.${this.__entityTag}.organization] Erreur lors de la création d'une instance organization :`, error.message);
|
|
381
|
+
throw error;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Récupérer les projets d'un utilisateur : Récupère la liste des projets auxquels l'utilisateur contribue.
|
|
387
|
+
* Constant : GET_PROJECTS_ADMIN | GET_PROJECTS_NO_ADMIN
|
|
388
|
+
*/
|
|
389
|
+
async getProjects(data = {}) {
|
|
390
|
+
delete data?.pathParams;
|
|
391
|
+
|
|
392
|
+
const fetchFn = this.isMe
|
|
393
|
+
? () => this.callIsMe(() => this.endpointApi.getProjectsAdmin(data))
|
|
394
|
+
: () => this.endpointApi.getProjectsNoAdmin(data);
|
|
395
|
+
|
|
396
|
+
if (!this.isMe && !data.filters) {
|
|
397
|
+
data.filters = {
|
|
398
|
+
"$or": {
|
|
399
|
+
[`links.contributors.${this.id}`]: { "$exists": true },
|
|
400
|
+
[`parent.${this.id}`]: { "$exists": true }
|
|
401
|
+
},
|
|
402
|
+
[`links.contributors.${this.id}`]: { "$exists": true }
|
|
403
|
+
// TODO : revoir les filtres pour harmoniser avec orga (schema pris de cocolight)
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const arrayObjetProjects = await fetchFn();
|
|
408
|
+
|
|
409
|
+
if (!Array.isArray(arrayObjetProjects.results)) {
|
|
410
|
+
throw new ApiResponseError("Erreur lors de la récupération des projets.", 500, arrayObjetProjects.results);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const rawProjectsList = arrayObjetProjects.results.map((projectData) =>
|
|
414
|
+
this.deps.Project.fromServerData(projectData, this, {
|
|
415
|
+
User,
|
|
416
|
+
News: this.deps.News,
|
|
417
|
+
EndpointApi: this.deps.EndpointApi
|
|
418
|
+
})
|
|
419
|
+
);
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
count: arrayObjetProjects?.count?.projects ?? 0,
|
|
423
|
+
results: rawProjectsList
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Crée une instance de projet et récupère son profil si nécessaire.
|
|
429
|
+
*
|
|
430
|
+
* @param {Object} projectData - Les données nécessaires pour initialiser le projet.
|
|
431
|
+
* @returns {Promise<Project>} Une promesse qui résout l'objet Projet créé.
|
|
432
|
+
* @throws {Error} Si une erreur se produit lors de la création du projet.
|
|
433
|
+
*/
|
|
434
|
+
async project(projectData = {}, ) {
|
|
435
|
+
try {
|
|
436
|
+
const project = new this.deps.Project(this, projectData, { User, News: this.deps.News, EndpointApi : this.deps.EndpointApi });
|
|
437
|
+
if (projectData.id || projectData.slug) {
|
|
438
|
+
await project.get();
|
|
439
|
+
}
|
|
440
|
+
return project;
|
|
441
|
+
} catch (error) {
|
|
442
|
+
this.apiClient._logger.error(`[Api.${this.__entityTag}.project] Erreur lors de la création d'une instance project :`, error.message);
|
|
443
|
+
throw error;
|
|
444
|
+
}
|
|
172
445
|
}
|
|
173
446
|
|
|
174
447
|
/**
|
|
175
|
-
* Récupérer les actualités : Récupère la liste
|
|
448
|
+
* Récupérer les actualités : Récupère la liste des actualités liées à l'utilisateur.
|
|
176
449
|
* Constant : GET_NEWS
|
|
177
450
|
*/
|
|
178
451
|
async getNews(data = {}) {
|
|
@@ -183,44 +456,81 @@ export class User {
|
|
|
183
456
|
// is not me add id
|
|
184
457
|
data.pathParams = { id: this.id };
|
|
185
458
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
* @param {boolean} data.markdownActive - Markdown activé (true/false) (default: true)
|
|
196
|
-
* @param {string} data.type - Type de l'objet, toujours 'news'. (default: "news")
|
|
197
|
-
* @param {boolean} data.json - Indique que la réponse est au format JSON. (default: true)
|
|
198
|
-
* @param {array | string} data.tags - Tags : "" pour effacer tous les tags, ou tableau de mots-clés.
|
|
199
|
-
* @param {object} data.mediaImg - Optionnel. Informations sur les images associées à la news.
|
|
200
|
-
* @param {number} data.mediaImg.countImages - Nombre d'images.
|
|
201
|
-
* @param {Array<string>} data.mediaImg.images - Liste des identifiants ou chemins d'images.
|
|
202
|
-
* @param {object} data.mediaFile - Optionnel. Informations sur les fichiers associés à la news.
|
|
203
|
-
* @param {number} data.mediaFile.countFiles - Nombre de fichiers.
|
|
204
|
-
* @param {Array<string>} data.mediaFile.files - Liste des identifiants ou chemins de fichiers.
|
|
205
|
-
* @param {object} data.mentions - Liste des mentions sous forme d'objet avec des clés dynamiques représentant l'indice de la mention.
|
|
206
|
-
* @param {Object.<string, object>} data.mentions - Objet dont les clés keys matching ^[0-9]+$
|
|
207
|
-
* @returns {Promise<Object>} - Les données de réponse.
|
|
208
|
-
* @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
|
|
209
|
-
* @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
|
|
210
|
-
* @throws {Error} - En cas d'erreur inattendue.
|
|
211
|
-
*/
|
|
212
|
-
async addNews(data = {}) {
|
|
213
|
-
if (data.parentId) {
|
|
214
|
-
delete data.parentId;
|
|
215
|
-
}
|
|
216
|
-
if (data.parentType) {
|
|
217
|
-
delete data.parentType;
|
|
218
|
-
}
|
|
219
|
-
return this.callIsMe(() => this._addNews(data));
|
|
459
|
+
const arrayObjetNews = await this.endpointApi.getNews(data);
|
|
460
|
+
if(!Array.isArray(arrayObjetNews)){
|
|
461
|
+
throw new ApiResponseError("Erreur lors de la récupération des actualités.", 500, arrayObjetNews);
|
|
462
|
+
}
|
|
463
|
+
const rawNewsList = arrayObjetNews.map((newsData) =>
|
|
464
|
+
this.deps.News.fromServerData(newsData, this, { User, EndpointApi: this.deps.EndpointApi })
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
return this._createFilteredProxy(rawNewsList);
|
|
220
468
|
}
|
|
221
|
-
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Crée une instance de news et la récupère si nécessaire.
|
|
472
|
+
*
|
|
473
|
+
* @param {Object} newsData - Les données nécessaires pour initialiser la news.
|
|
474
|
+
* @returns {Promise<News>} Une promesse qui résout l'objet News créé.
|
|
475
|
+
* @throws {Error} Si une erreur se produit lors de la création de la news.
|
|
476
|
+
*/
|
|
477
|
+
async news(newsData = {}, ) {
|
|
478
|
+
try {
|
|
479
|
+
const news = new this.deps.News(this, newsData, { User, EndpointApi : this.deps.EndpointApi });
|
|
480
|
+
if (newsData.id) {
|
|
481
|
+
await news.get();
|
|
482
|
+
}
|
|
483
|
+
return news;
|
|
484
|
+
} catch (error) {
|
|
485
|
+
this.apiClient._logger.error(`[Api.${this.__entityTag}.news] Erreur lors de la création d'une instance news :`, error.message);
|
|
486
|
+
throw error;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
_updateInitialDraftSnapshot() {
|
|
491
|
+
this.#initialDraftData = JSON.parse(JSON.stringify(this.#draftData));
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
hasChanges() {
|
|
495
|
+
return JSON.stringify(this.#draftData) !== JSON.stringify(this.#initialDraftData);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Champs par défaut pour les schemas json ou l'on extrait les fields. (pour les if/else/then)
|
|
500
|
+
*
|
|
501
|
+
* @property {Object} defaultFields - Un objet contenant les propriétés par défaut pour l'entité User.
|
|
502
|
+
*/
|
|
503
|
+
defaultFields = {
|
|
504
|
+
typeElement: this.getEntityType(),
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Champs à supprimer de draft lors de la construction du proxy.
|
|
509
|
+
*
|
|
510
|
+
* @property {Array<string>} removeFields - Un tableau de chaînes représentant les champs à supprimer.
|
|
511
|
+
*/
|
|
512
|
+
removeFields = [
|
|
513
|
+
"typeElement",
|
|
514
|
+
];
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Transformateurs appliqués lors de la lecture du draft.
|
|
518
|
+
*
|
|
519
|
+
* @type {Object<string, function>}
|
|
520
|
+
*/
|
|
521
|
+
transforms = {
|
|
522
|
+
github: (val, full) => full?.socialNetwork?.github,
|
|
523
|
+
gitlab: (val, full) => full?.socialNetwork?.gitlab,
|
|
524
|
+
facebook: (val, full) => full?.socialNetwork?.facebook,
|
|
525
|
+
twitter: (val, full) => full?.socialNetwork?.twitter,
|
|
526
|
+
instagram: (val, full) => full?.socialNetwork?.instagram,
|
|
527
|
+
diaspora: (val, full) => full?.socialNetwork?.diaspora,
|
|
528
|
+
mastodon: (val, full) => full?.socialNetwork?.mastodon,
|
|
529
|
+
telegram: (val, full) => full?.socialNetwork?.telegram,
|
|
530
|
+
signal: (val, full) => full?.socialNetwork?.signal
|
|
531
|
+
};
|
|
222
532
|
}
|
|
223
533
|
|
|
224
534
|
// Incorporation des mixins dans User
|
|
225
|
-
Object.assign(User.prototype,
|
|
535
|
+
Object.assign(User.prototype, MutualEntityMixin, UtilMixin, UserMixin, DraftStateMixin);
|
|
226
536
|
|
package/src/api/UserApi.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// UserApi.js
|
|
2
2
|
import ApiClient from "../ApiClient.js";
|
|
3
3
|
import { ApiResponseError } from "../error.js";
|
|
4
|
+
import EndpointApi from "./EndpointApi.js";
|
|
5
|
+
import { News } from "./News.js";
|
|
6
|
+
import { Organization } from "./Organization.js";
|
|
7
|
+
import { Project } from "./Project.js";
|
|
4
8
|
import { User } from "./User.js";
|
|
5
9
|
|
|
6
10
|
export class UserApi {
|
|
@@ -15,7 +19,7 @@ export class UserApi {
|
|
|
15
19
|
// Appel à un endpoint d'authentification
|
|
16
20
|
const response = await this.client.callEndpoint("AUTHENTICATE_URL", { email, password });
|
|
17
21
|
// Création d'une instance de LoggedInUser à partir des données reçues
|
|
18
|
-
this.loggedUser = new User(this.client,
|
|
22
|
+
this.loggedUser = new User(this.client, response.data.user, { EndpointApi, Organization, Project, News });
|
|
19
23
|
return this.loggedUser;
|
|
20
24
|
});
|
|
21
25
|
}
|