@communecter/cocolight-api-client 1.0.18 → 1.0.20

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.
@@ -1,15 +1,6 @@
1
- import { ApiError } from "../error.js";
2
- import { DraftStateMixin } from "../mixin/DraftStateMixin.js";
3
- import { EntityMixin } from "../mixin/EntityMixin.js";
4
- import { MutualEntityMixin } from "../mixin/MutualEntityMixin.js";
5
- import { NewsMixin } from "../mixin/NewsMixin.js";
6
- import { UtilMixin } from "../mixin/UtilMixin.js";
7
-
8
- export class Project {
9
- #draftData = {};
10
- #initialDraftData = {};
11
- #serverData = null;
1
+ import BaseEntity from "./BaseEntity.js";
12
2
 
3
+ export class Project extends BaseEntity {
13
4
  static entityType = "projects";
14
5
 
15
6
  static SCHEMA_CONSTANTS = [
@@ -36,196 +27,78 @@ export class Project {
36
27
  ["PROFIL_IMAGE", "updateImageProfil"]
37
28
  ]);
38
29
 
39
- /**
40
- * Crée une instance de Project.
41
- *
42
- * @param {ApiClient|User|Organization|Project} parent - Instance de ApiClient, User, Organization ou Project.
43
- * @param {Object} [data={}] - Données de l'organisation.
44
- * @param {Object} [deps={}] - Dépendances injectées.
45
- * @param {function|object} deps.EndpointApi - Classe ou instance de EndpointApi pour les appels API.
46
- * @param {function} deps.User - Classe User pour la gestion des utilisateurs.
47
- * @param {function} deps.News - Classe News pour la gestion des actualités.
48
- *
49
- * @throws {ApiError} Si le parent n'est pas valide ou si les dépendances ne sont pas injectées correctement.
50
- */
51
- constructor(parent, data = {}, deps = {}) {
52
- this.__entityTag = "Project";
53
-
54
- if (!deps.EndpointApi) throw new ApiError("EndpointApi class must be injected to avoid circular dependency.");
55
- if (!deps.User) throw new ApiError("User class must be injected.");
56
- if (!deps.News) throw new ApiError("News class must be injected.");
57
-
58
- if (!parent) throw new ApiError("Parent is required.");
59
-
60
- this.deps = deps;
61
-
62
- this.EndpointApiClass = deps.EndpointApi;
63
-
64
- if (parent?.__entityTag === "ApiClient") {
65
- this.apiClient = parent;
66
- this.parent = null;
67
- } else if (parent?.__entityTag === "User" || parent?.__entityTag === "Organization" || parent?.__entityTag === "Project") {
68
- this.apiClient = parent.apiClient;
69
- this.parent = parent;
70
- } else {
71
- throw new ApiError("Invalid parent for Project.");
72
- }
73
-
74
- this.endpointApi = typeof deps.EndpointApi === "function"
75
- ? new deps.EndpointApi(this.apiClient)
76
- : (typeof deps.EndpointApi === "object"
77
- ? deps.EndpointApi
78
- : (() => { throw new ApiError("deps.EndpointApi must be a class or instance."); })());
79
-
80
- const { draft, proxy } = this._buildDraftAndProxy({
81
- data: { ...data, ...this.defaultFields },
82
- serverData: this.#serverData,
83
- constant: Project.SCHEMA_CONSTANTS,
84
- apiClient: this.apiClient,
85
- transforms: this.transforms,
86
- removeFields: this.removeFields
87
- });
88
-
89
- this.#initialDraftData = JSON.parse(JSON.stringify(draft));
90
- this.#draftData = draft;
91
- this.data = proxy;
92
- }
93
-
94
- get id() {
95
- return this.#draftData.id || null;
96
- }
97
-
98
- _id(newId) {
99
- this.#draftData.id = newId;
100
- }
101
-
102
- get isConnected() {
103
- return this.apiClient.isConnected;
104
- }
105
-
106
- get userId() {
107
- return this.apiClient.userId;
108
- }
109
-
110
- get draftData() {
111
- return this.#draftData;
112
- }
113
-
114
- get initialDraftData() {
115
- return this.#initialDraftData;
116
- }
117
-
118
- get serverData() {
119
- return this.#serverData;
120
- }
121
-
122
- get isMe() {
123
- return this.isConnected && this.userId === this.parent?.id;
124
- }
125
-
126
- getEntityType() {
127
- return Project.entityType;
128
- }
129
-
130
- _updateInitialDraftSnapshot() {
131
- this.#initialDraftData = JSON.parse(JSON.stringify(this.#draftData));
132
- }
133
-
134
- hasChanges() {
135
- return JSON.stringify(this.#draftData) !== JSON.stringify(this.#initialDraftData);
136
- }
137
-
138
- _setData(newData) {
139
- this.#serverData = { ...newData };
140
- const { draft, proxy } = this._buildDraftAndProxy({
141
- data: { ...newData, ...this.defaultFields },
142
- serverData: this.#serverData,
143
- constant: Project.SCHEMA_CONSTANTS,
144
- apiClient: this.apiClient,
145
- transforms: this.transforms,
146
- removeFields: this.removeFields
147
- });
148
- this.#initialDraftData = JSON.parse(JSON.stringify(draft));
149
- this.#draftData = draft;
150
- this.data = proxy;
151
- }
152
-
153
- async refresh() {
154
- if (!this.id) throw new ApiError("Impossible de rafraîchir sans ID.");
155
- return this.get();
156
- }
30
+ defaultFields = {
31
+ typeElement: this.getEntityType()
32
+ };
157
33
 
158
- async save() {
34
+ removeFields = [
35
+ "typeElement"
36
+ ];
159
37
 
160
- if(!this.isConnected){
161
- throw new ApiError("Impossible de sauvegarder sans être connecté.");
38
+ // links.contributors.${this.userId}.isAdmin === true
39
+ transforms = {
40
+ github: (val, full) => full?.socialNetwork?.github,
41
+ gitlab: (val, full) => full?.socialNetwork?.gitlab,
42
+ facebook: (val, full) => full?.socialNetwork?.facebook,
43
+ twitter: (val, full) => full?.socialNetwork?.twitter,
44
+ instagram: (val, full) => full?.socialNetwork?.instagram,
45
+ diaspora: (val, full) => full?.socialNetwork?.diaspora,
46
+ mastodon: (val, full) => full?.socialNetwork?.mastodon,
47
+ telegram: (val, full) => full?.socialNetwork?.telegram,
48
+ signal: (val, full) => full?.socialNetwork?.signal,
49
+ parent: (val) => {
50
+ if (!val || typeof val !== "object") return null;
51
+
52
+ return Object.fromEntries(
53
+ Object.entries(val).map(([key, obj]) => [
54
+ key,
55
+ {
56
+ type: obj?.type ?? null,
57
+ name: obj?.name ?? null
58
+ }
59
+ ])
60
+ );
162
61
  }
62
+ };
163
63
 
164
- const payload = { ...this.#draftData };
165
-
166
- if (!this.id) {
167
- await this._add(payload);
168
- // this._updateInitialDraftSnapshot();
169
- await this.refresh();
170
- return this.#serverData;
171
- } else {
172
- const hasChanged = await this._update(payload);
173
- if (hasChanged) {
174
- // this._updateInitialDraftSnapshot();
175
- await this.refresh();
176
- }
177
- return this.#serverData;
64
+ async _add(payload) {
65
+ if (!this._calledFromSave) {
66
+ throw new Error("utilisation invalide de _add, utilisez save");
178
67
  }
179
-
180
- }
181
68
 
182
- async _add(payload){
183
- // si pas d'id on le crée
184
- payload.id = this._newId();
185
- // on enlève le slug mais il ne devrait pas être là
186
- if(payload.slug){
187
- delete payload.slug;
188
- }
69
+ payload.id = this._newId?.();
70
+ if (payload.slug) delete payload.slug;
189
71
 
190
72
  for (const [constant, methodName] of Project.ADD_BLOCKS) {
191
73
  const blockData = this._extractChangedFieldsFromSchema(
192
74
  this.apiClient,
193
75
  constant,
194
- { ...payload, ...this.defaultFields},
76
+ { ...payload, ...this.defaultFields },
195
77
  () => {}
196
78
  );
197
79
  if (blockData && Object.keys(blockData).length > 0) {
198
80
  const data = await this[methodName](blockData);
199
-
200
81
  if (!this.id && data?.map?.id) {
201
- this.#draftData.id = data.map.id;
202
- this.#draftData.slug = data.map.slug;
203
- // on met à jour le slug dans le draftData
204
-
205
- // faire ça ou alors resfresh() pour re-synchroniser
206
- // this.#serverData = data.map;
82
+ this._draftData.id = data.map.id;
83
+ this._draftData.slug = data.map.slug;
207
84
  }
208
85
  }
209
86
  }
210
87
  }
211
88
 
212
- async _update(payload){
213
- // on enlève l'id car il existe déjà dans les appels API je laisse slug car il peut être changer en update ici
214
- // if(payload.slug){
215
- // delete payload.slug;
216
- // }
217
- if(payload.id){
218
- delete payload.id;
89
+ async _update(payload) {
90
+ if (!this._calledFromSave) {
91
+ throw new Error("utilisation invalide de _update, utilisez save");
219
92
  }
220
93
 
94
+ if (payload.id) delete payload.id;
221
95
  let hasChanged = false;
222
96
 
223
- // Sinon, on fait les updates en blocs
224
97
  for (const [constant, methodName] of Project.UPDATE_BLOCKS) {
225
98
  const blockData = this._extractChangedFieldsFromSchema(
226
99
  this.apiClient,
227
100
  constant,
228
- { ...payload, ...this.defaultFields},
101
+ { ...payload, ...this.defaultFields },
229
102
  () => this.initialDraftData,
230
103
  this.removeFields
231
104
  );
@@ -234,11 +107,11 @@ export class Project {
234
107
  hasChanged = true;
235
108
  }
236
109
  }
237
-
110
+
238
111
  return hasChanged;
239
112
  }
240
113
 
241
- addProject(data = {}) {
114
+ async addProject(data = {}) {
242
115
 
243
116
  // le parent n'est pas me donc on doit ajouter le parent
244
117
  if (!this.isMe) {
@@ -252,74 +125,91 @@ export class Project {
252
125
  return this.callIsConnected(() => this.endpointApi.addProject(data));
253
126
  }
254
127
 
255
- static fromServerData(data, parent, deps) {
256
- const instance = new Project(parent, {}, deps);
257
- instance.#serverData = { ...data };
128
+ async getOrganizations() {
129
+ throw new Error(`getOrganizations n'existe pas dans ${this.constructor.name}`);
130
+ }
258
131
 
259
- const { draft, proxy } = instance._buildDraftAndProxy({
260
- data: { ...data, ...instance.defaultFields },
261
- serverData: instance.#serverData,
262
- constant: Project.SCHEMA_CONSTANTS,
263
- apiClient: instance.apiClient,
264
- transforms: instance.transforms,
265
- removeFields: instance.removeFields
266
- });
132
+ async getProjects(data = {}) {
133
+ return super.getProjects(data);
134
+ }
267
135
 
268
- instance.#draftData = draft;
269
- instance.data = proxy;
136
+ async getEvents() {
137
+ throw new Error(`getEvents pas encore implémenté dans ${this.constructor.name}`);
138
+ }
270
139
 
271
- return instance;
140
+ async getPois(data = {}) {
141
+ return super.getPois(data);
272
142
  }
273
143
 
144
+ async getBadgesIssuer(data = {}) {
145
+ return super.getBadgesIssuer(data);
146
+ }
274
147
 
275
- defaultFields = {
276
- typeElement: this.getEntityType()
277
- };
148
+ async getNews(data = {}) {
149
+ return super.getNews(data);
150
+ }
278
151
 
279
- removeFields = [
280
- "typeElement"
281
- ];
282
-
283
- // role = admin c'est bizarre car en faite c'est gérer dans links sur user et l'orga
284
- // links.members.${this.userId}.isAdmin === true
285
- transforms = {
286
- github: (val, full) => full?.socialNetwork?.github,
287
- gitlab: (val, full) => full?.socialNetwork?.gitlab,
288
- facebook: (val, full) => full?.socialNetwork?.facebook,
289
- twitter: (val, full) => full?.socialNetwork?.twitter,
290
- instagram: (val, full) => full?.socialNetwork?.instagram,
291
- diaspora: (val, full) => full?.socialNetwork?.diaspora,
292
- mastodon: (val, full) => full?.socialNetwork?.mastodon,
293
- telegram: (val, full) => full?.socialNetwork?.telegram,
294
- signal: (val, full) => full?.socialNetwork?.signal,
295
- parent: (val) => {
296
- if (!val || typeof val !== "object") return null;
297
-
298
- return Object.fromEntries(
299
- Object.entries(val).map(([key, obj]) => [
300
- key,
301
- {
302
- type: obj?.type ?? null,
303
- name: obj?.name ?? null
304
- }
305
- ])
306
- );
307
- }
308
- };
152
+ async getSubscribers(data = {}) {
153
+ return super.getSubscribers(data);
154
+ }
309
155
 
310
- async project(projectData = {}, ) {
311
- try {
312
- const project = new Project(this, projectData, { User: this.deps.User, News: this.deps.News, EndpointApi : this.deps.EndpointApi });
313
- if (projectData.id || projectData.slug) {
314
- await project.get();
315
- }
316
- return project;
317
- } catch (error) {
318
- this.apiClient._logger.error(`[Api.${this.__entityTag}.project] Erreur lors de la création d'une instance project :`, error.message);
319
- throw error;
320
- }
156
+ /**
157
+ * Crée une instance de projet et récupère son profil si nécessaire.
158
+ *
159
+ * @param {Object} projectData - Les données nécessaires pour initialiser le projet.
160
+ * @returns {Promise<Project>} Une promesse qui résout l'objet Projet créé.
161
+ * @throws {Error} Si une erreur se produit lors de la création du projet.
162
+ */
163
+ async project(projectData = {}) {
164
+ // TODO: Vérifier si l'utilisateur est admin du projet
165
+ return super.project(projectData);
321
166
  }
322
167
 
323
- }
168
+ /**
169
+ * Crée une instance de POI et la récupère si nécessaire.
170
+ *
171
+ * @param {Object} poiData - Les données nécessaires pour initialiser le POI.
172
+ * @returns {Promise<Poi>} Une promesse qui résout l'objet POI créé.
173
+ * @throws {Error} Si une erreur se produit lors de la création du POI.
174
+ */
175
+ async poi(poiData = {}) {
176
+ // TODO: Vérifier si l'utilisateur est admin de l'organisation
177
+ return super.poi(poiData);
178
+ }
179
+
180
+ /**
181
+ * Crée une instance d'événement et la récupère si nécessaire.
182
+ *
183
+ * @param {Object} eventData - Les données nécessaires pour initialiser l'événement.
184
+ * @returns {Promise<Event>} Une promesse qui résout l'objet Événement créé.
185
+ * @throws {Error} Si une erreur se produit lors de la création de l'événement.
186
+ */
187
+ async event(eventData = {}) {
188
+ // TODO: Vérifier si l'utilisateur est admin de l'organisation
189
+ return super.event(eventData);
190
+ }
191
+
192
+ /**
193
+ * Crée une instance de badge et la récupère si nécessaire.
194
+ *
195
+ * @param {Object} badgeData - Les données nécessaires pour initialiser le badge.
196
+ * @returns {Promise<Badge>} Une promesse qui résout l'objet Badge créé.
197
+ * @throws {Error} Si une erreur se produit lors de la création du badge.
198
+ */
199
+ async badge(badgeData = {}) {
200
+ // TODO: Vérifier si l'utilisateur est admin de l'organisation
201
+ return super.badge(badgeData);
202
+ }
203
+
204
+ /**
205
+ * Crée une instance de news et la récupère si nécessaire.
206
+ *
207
+ * @param {Object} newsData - Les données nécessaires pour initialiser la news.
208
+ * @returns {Promise<News>} Une promesse qui résout l'objet News créé.
209
+ * @throws {Error} Si une erreur se produit lors de la création de la news.
210
+ */
211
+ async news(newsData = {}) {
212
+ return super.news(newsData);
213
+ }
324
214
 
325
- Object.assign(Project.prototype, UtilMixin, MutualEntityMixin, EntityMixin, NewsMixin, DraftStateMixin);
215
+ }