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