@communecter/cocolight-api-client 1.0.10 → 1.0.12

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/README.md CHANGED
@@ -38,12 +38,14 @@ package.json # Dépendances, scripts, métadonnées
38
38
  ### ESM
39
39
 
40
40
  ```js
41
- import { ApiClient, Api } from "@communecter/cocolight-api-client";
41
+ import Cocolight from "@communecter/cocolight-api-client";
42
+
43
+ const { Api, ApiClient, tokenStorageStrategy } = Cocolight;
42
44
  ```
43
45
  ### CommonJS
44
46
 
45
47
  ```js
46
- const { ApiClient, Api } = require("@communecter/cocolight-api-client").default;
48
+ const { ApiClient, Api, tokenStorageStrategy } = require("@communecter/cocolight-api-client").default;
47
49
  ```
48
50
 
49
51
  ### 🔗 Intégration via CDN
@@ -221,7 +223,287 @@ pathParams: {
221
223
  }
222
224
  ```
223
225
 
224
- Ces valeurs seront automatiquement résolues à partir du contexte du client.
226
+ ## 🎩 API de façade : `Api`
227
+
228
+ La classe `Api` fournit une interface unifiée pour gérer les utilisateurs, organisations, projets et actualités. Elle encapsule les appels à `ApiClient` et permet de manipuler les entités comme des objets métier avec des méthodes pratiques.
229
+
230
+ ### 🧪 Authentification
231
+
232
+ #### `Api.userLogin(email, password, options)`
233
+ Crée une instance d’`Api` authentifiée.
234
+
235
+ ```js
236
+ const api = await Api.userLogin("john@doe.com", "password123", { baseURL: "https://api.monapp.com" });
237
+ const user = await api.me();
238
+ ```
239
+
240
+ #### `Api.userApi(options)`
241
+ Retourne une instance `UserApi` si tu veux gérer manuellement l’authentification :
242
+
243
+ ```js
244
+ const userApi = Api.userApi({ baseURL: "..." });
245
+ const user = await userApi.login("email", "mdp");
246
+ ```
247
+
248
+ ---
249
+
250
+ ### 🔐 Session et utilisateur courant
251
+
252
+ #### `api.me()`
253
+ Retourne l'utilisateur actuellement connecté (`User`).
254
+
255
+ ```js
256
+ const user = await api.me();
257
+ console.log(user.data.email);
258
+ ```
259
+
260
+ ---
261
+
262
+ ### 👤 Utilisateurs
263
+
264
+ #### `api.user(userData)`
265
+ Crée une instance `User` (autre que le connecté).
266
+
267
+ ```js
268
+ const otherUser = await api.user({ slug: "caroline" });
269
+ console.log(otherUser.data.description);
270
+ ```
271
+
272
+ ---
273
+
274
+ ### 🏛️ Organisations
275
+
276
+ #### `api.organization({ id | slug })`
277
+ Retourne une instance d’`Organization`. Récupère automatiquement le profil public.
278
+
279
+ ```js
280
+ const orga = await api.organization({ slug: "asso-verte" });
281
+ console.log(orga.data.name);
282
+ ```
283
+
284
+ ---
285
+
286
+ ### 🏗️ Projets
287
+
288
+ #### `api.project({ id | slug })`
289
+ Retourne une instance `Project`. Récupère automatiquement le profil public.
290
+
291
+ ```js
292
+ const projet = await api.project({ id: "647..." });
293
+ ```
294
+
295
+ ---
296
+
297
+ ## 📦 Entités métiers
298
+
299
+ Les entités suivantes partagent une API commune grâce aux mixins : `User`, `Organization`, `Project`, `News`.
300
+
301
+ ### Propriétés
302
+
303
+ | Propriété | Description |
304
+ |------------------|-------------|
305
+ | `data` | Proxy combiné `serverData + draftData` |
306
+ | `draftData` | Données modifiables avant `save()` |
307
+ | `initialDraftData` | Snapshot initial pour détection des changements |
308
+ | `serverData` | Dernières données serveur |
309
+ | `isConnected` | Vrai si `ApiClient` a un token |
310
+ | `userId` | ID de l'utilisateur connecté |
311
+ | `isMe` | Vrai si l'entité correspond à l'utilisateur courant |
312
+
313
+ ---
314
+
315
+ ### Méthodes génériques
316
+
317
+ #### `entity.save()`
318
+ Sauvegarde les données via les blocs modifiés (`UPDATE_BLOCK_*`, `ADD_*`).
319
+
320
+ #### `entity.refresh()`
321
+ Recharge les données depuis le serveur.
322
+
323
+ #### `entity.hasChanges()`
324
+ Retourne `true` si le draft est différent du snapshot initial.
325
+
326
+ ---
327
+
328
+ ## ✏️ Méthodes d’édition (communes à toutes les entités)
329
+
330
+ | Méthode | Description |
331
+ |------------------------|-------------|
332
+ | `updateDescription` | Met à jour les champs `shortDescription`, `description`, `descMentions` |
333
+ | `updateInfo` | Nom, email, téléphone, etc. |
334
+ | `updateSocial` | Réseaux sociaux (Facebook, GitHub...) |
335
+ | `updateLocality` | Adresse, géolocalisation |
336
+ | `updateSlug` | Slug de l’URL |
337
+ | `updateImageProfil` | Upload de l’avatar |
338
+
339
+ ---
340
+
341
+ ## 📰 Actualités (`News`)
342
+
343
+ Créées à partir d’un `User`, `Organization` ou `Project`.
344
+
345
+ ### Création
346
+
347
+ ```js
348
+ const news = await orga.news();
349
+ news.data.text = "Nouvelle actu !";
350
+ await news.save();
351
+ ```
352
+
353
+ ### Gestion
354
+
355
+ | Méthode | Description |
356
+ |----------------|-------------|
357
+ | `addMention({ slug \| id })` | Ajoute une mention à la news |
358
+ | `addImage(file)` | Ajoute une image (via validation MIME) |
359
+ | `addFile(file)` | Ajoute un fichier (PDF, CSV...) |
360
+ | `delete()` | Supprime la news |
361
+ | `refresh()` | Recharge la news |
362
+ | `get()` | Récupère les données à partir de l’ID |
363
+
364
+ ---
365
+
366
+ ## 🔄 Utilisation des schémas de validation (AJV)
367
+
368
+ Toutes les entités sont basées sur les constantes de schéma :
369
+ - `ADD_*`
370
+ - `UPDATE_BLOCK_*`
371
+ - `PROFIL_IMAGE`
372
+
373
+ Ces constantes sont mappées automatiquement pour les appels `save()`, `updateX()`, etc.
374
+
375
+ ---
376
+
377
+ ## ✅ Exemple : mise à jour d’un projet
378
+
379
+ ```js
380
+ const projet = await api.project({ slug: "bio-bazar" });
381
+ projet.data.description = "Nouveau descriptif de mon projet.";
382
+ if (projet.hasChanges()) {
383
+ await projet.save();
384
+ }
385
+ ```
386
+
387
+ ## 👤 API : Utilisateur (`User`)
388
+
389
+ Une instance `User` offre un ensemble de méthodes métier pour interagir avec les projets, organisations et actualités de l’utilisateur.
390
+
391
+ ---
392
+
393
+ ### 🔍 Chargement
394
+
395
+ ```js
396
+ const user = await api.user({ slug: "caroline" });
397
+ await user.get();
398
+ ```
399
+
400
+ ---
401
+
402
+ ### 🏭 Création d'entités depuis `User`
403
+
404
+ Un utilisateur peut **créer** :
405
+
406
+ #### ➕ Organisation
407
+
408
+ ```js
409
+ const orga = await user.organization({ name: "Ma nouvelle asso" });
410
+ await orga.save(); // appelle ADD_ORGANIZATION puis rafraîchit les données
411
+ ```
412
+
413
+ #### ➕ Projet
414
+
415
+ ```js
416
+ const projet = await user.project({ name: "Mon projet citoyen" });
417
+ await projet.save(); // appelle ADD_PROJECT
418
+ ```
419
+
420
+ #### ➕ Actualité
421
+
422
+ ```js
423
+ const news = await user.news({ text: "Hello world 🌍" });
424
+ await news.save(); // appelle ADD_NEWS
425
+ ```
426
+
427
+ ---
428
+
429
+ ### 📦 Récupération des projets de l'utilisateur
430
+
431
+ #### `user.getProjects()`
432
+
433
+ Retourne la liste des projets créés ou co-administrés par l’utilisateur.
434
+
435
+ ```js
436
+ const { results: projets } = await user.getProjects();
437
+ console.log("Projets liés à l'utilisateur :", projets.map(p => p.data.name));
438
+ ```
439
+
440
+ ---
441
+
442
+ ### 🧑‍🤝‍🧑 Récupération des organisations de l'utilisateur
443
+
444
+ #### `user.getOrganizations()`
445
+
446
+ Retourne les organisations où il est membre (admin ou non).
447
+
448
+ ```js
449
+ const { results: orgs } = await user.getOrganizations();
450
+ console.log("Organisations :", orgs.map(o => o.data.name));
451
+ ```
452
+
453
+ ---
454
+
455
+ ### 📰 Actualités associées
456
+
457
+ #### `user.getNews()`
458
+
459
+ Retourne toutes les actualités liées à l’utilisateur.
460
+
461
+ ```js
462
+ const newsList = await user.getNews({ indexStep: 5 });
463
+ ```
464
+
465
+ #### `user.news(newsData)`
466
+
467
+ Crée une nouvelle actualité, ou charge une existante si `id` est fourni.
468
+
469
+ ```js
470
+ const actu = await user.news({ text: "Ceci est une nouvelle actu" });
471
+ await actu.save();
472
+ ```
473
+
474
+ ---
475
+
476
+ ### ⚙️ Mise à jour du profil utilisateur
477
+
478
+ Les méthodes `updateX` disponibles sont :
479
+
480
+ - `updateDescription(data)`
481
+ - `updateInfo(data)`
482
+ - `updateSocial(data)`
483
+ - `updateLocality(data)`
484
+ - `updateSlug({ slug })`
485
+ - `updateImageProfil({ profil_avatar })`
486
+ - `updateSettings({ type, value })`
487
+
488
+ ---
489
+
490
+ ### 🔑 Sécurité et gestion de compte
491
+
492
+ #### Modifier mot de passe
493
+
494
+ ```js
495
+ await user.changePassword({
496
+ oldPassword: "secret1",
497
+ newPassword: "secret2",
498
+ newPassword2: "secret2"
499
+ });
500
+ ```
501
+
502
+ #### Supprimer son compte
503
+
504
+ ```js
505
+ await user.delete({ reason: "Je souhaite quitter la plateforme" });
506
+ ```
225
507
 
226
508
  ## Licence
227
509
 
@@ -0,0 +1 @@
1
+ (this.webpackChunkCocolightApiClient=this.webpackChunkCocolightApiClient||[]).push([[405],{870:()=>{},4061:()=>{},6497:()=>{},8405:(e,i,t)=>{"use strict";t.d(i,{FileStorageStrategy:()=>h});var r=t(6497),s=t(870),n=t(4061),c=t(1027);class h extends c.u3{constructor(e="tokens.json",i=n.join(s.homedir(),".config","cocolight")){super(),this.dir=i,this.filePath=n.join(i,e),this._ensureDirectoryExists()}_ensureDirectoryExists(){r.existsSync(this.dir)||r.mkdirSync(this.dir,{recursive:!0})}_readFile(){if(!r.existsSync(this.filePath))return{};try{return JSON.parse(r.readFileSync(this.filePath,"utf8"))}catch(e){return console.error("Error reading token file:",e),{}}}_writeFile(e){r.writeFileSync(this.filePath,JSON.stringify(e,null,2),"utf8")}getAccessToken(){return this._readFile().accessToken||null}setAccessToken(e){const i=this._readFile();i.accessToken=e,this._writeFile(i)}getRefreshToken(){return this._readFile().refreshToken||null}setRefreshToken(e){const i=this._readFile();i.refreshToken=e,this._writeFile(i)}clear(){this._writeFile({})}}}}]);
@@ -0,0 +1 @@
1
+ "use strict";(self.webpackChunk_communecter_cocolight_api_client=self.webpackChunk_communecter_cocolight_api_client||[]).push([[405],{405:(e,i,t)=>{t.d(i,{FileStorageStrategy:()=>o});var r=t(383),s=t(366),n=t(3),c=t(27);class o extends c.u3{constructor(e="tokens.json",i=n.join(s.homedir(),".config","cocolight")){super(),this.dir=i,this.filePath=n.join(i,e),this._ensureDirectoryExists()}_ensureDirectoryExists(){r.existsSync(this.dir)||r.mkdirSync(this.dir,{recursive:!0})}_readFile(){if(!r.existsSync(this.filePath))return{};try{return JSON.parse(r.readFileSync(this.filePath,"utf8"))}catch(e){return console.error("Error reading token file:",e),{}}}_writeFile(e){r.writeFileSync(this.filePath,JSON.stringify(e,null,2),"utf8")}getAccessToken(){return this._readFile().accessToken||null}setAccessToken(e){const i=this._readFile();i.accessToken=e,this._writeFile(i)}getRefreshToken(){return this._readFile().refreshToken||null}setRefreshToken(e){const i=this._readFile();i.refreshToken=e,this._writeFile(i)}clear(){this._writeFile({})}}}}]);
@@ -0,0 +1 @@
1
+ export const __webpack_id__=790;export const __webpack_ids__=[790];export const __webpack_modules__={790:(e,t,r)=>{r.d(t,{FileStorageStrategy:()=>o});var i=r(421),s=r(116),n=r(521),l=r(72);class o extends l.u3{constructor(e="tokens.json",t=n.default.join(s.default.homedir(),".config","cocolight")){super(),this.dir=t,this.filePath=n.default.join(t,e),this._ensureDirectoryExists()}_ensureDirectoryExists(){i.default.existsSync(this.dir)||i.default.mkdirSync(this.dir,{recursive:!0})}_readFile(){if(!i.default.existsSync(this.filePath))return{};try{return JSON.parse(i.default.readFileSync(this.filePath,"utf8"))}catch(e){return console.error("Error reading token file:",e),{}}}_writeFile(e){i.default.writeFileSync(this.filePath,JSON.stringify(e,null,2),"utf8")}getAccessToken(){return this._readFile().accessToken||null}setAccessToken(e){const t=this._readFile();t.accessToken=e,this._writeFile(t)}getRefreshToken(){return this._readFile().refreshToken||null}setRefreshToken(e){const t=this._readFile();t.refreshToken=e,this._writeFile(t)}clear(){this._writeFile({})}}}};