@communecter/cocolight-api-client 1.0.116 → 1.0.117
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/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/dist/cocolight-api-client.vite.mjs.js +1 -1
- package/dist/cocolight-api-client.vite.mjs.js.map +1 -1
- package/package.json +1 -1
- package/src/api/BaseEntity.ts +183 -148
- package/src/api/Event.ts +0 -8
- package/src/api/Organization.ts +10 -0
- package/src/api/Project.ts +10 -0
- package/src/api/User.ts +97 -76
- package/types/api/BaseEntity.d.ts +90 -21
- package/types/api/Organization.d.ts +7 -0
- package/types/api/Project.d.ts +7 -0
- package/types/api/User.d.ts +46 -10
package/package.json
CHANGED
package/src/api/BaseEntity.ts
CHANGED
|
@@ -250,6 +250,7 @@ interface MinimalUserLink {
|
|
|
250
250
|
isInviting?: boolean;
|
|
251
251
|
isAdminInviting?: boolean;
|
|
252
252
|
isAdminPending?: boolean;
|
|
253
|
+
isAdmin?: boolean;
|
|
253
254
|
}
|
|
254
255
|
|
|
255
256
|
// Types pour linkEntitiesFromServerData
|
|
@@ -2557,15 +2558,11 @@ export class BaseEntity<TServerData = any> {
|
|
|
2557
2558
|
// Cas : aucun lien → on demande à se connecter
|
|
2558
2559
|
if (!userLink) {
|
|
2559
2560
|
|
|
2560
|
-
const t = this.getEntityType();
|
|
2561
|
-
|
|
2562
2561
|
// 1) Garde runtime pour exclure les types non pris en charge par ConnectData
|
|
2563
|
-
|
|
2564
|
-
throw new ApiError(`Le type d'entité "${t}" ne supporte pas cette connexion.`, 400);
|
|
2565
|
-
}
|
|
2562
|
+
this._assertNotEntityType("connect", ["poi", "badges", "news"]);
|
|
2566
2563
|
|
|
2567
2564
|
// 2) Narrow de type pour TypeScript
|
|
2568
|
-
const parentType =
|
|
2565
|
+
const parentType = this.getEntityType() as ConnectData["parentType"];
|
|
2569
2566
|
|
|
2570
2567
|
const data: ConnectData = {
|
|
2571
2568
|
childId: this.userId,
|
|
@@ -2617,15 +2614,11 @@ export class BaseEntity<TServerData = any> {
|
|
|
2617
2614
|
// Aucun lien existant → envoie une demande avec rôle "admin"
|
|
2618
2615
|
if (!userLink) {
|
|
2619
2616
|
|
|
2620
|
-
const t = this.getEntityType();
|
|
2621
|
-
|
|
2622
2617
|
// 1) Garde runtime pour exclure les types non pris en charge par ConnectData
|
|
2623
|
-
|
|
2624
|
-
throw new ApiError(`Le type d'entité "${t}" ne supporte pas cette connexion.`, 400);
|
|
2625
|
-
}
|
|
2618
|
+
this._assertNotEntityType("connect", ["poi", "badges", "news"]);
|
|
2626
2619
|
|
|
2627
2620
|
// 2) Narrow de type pour TypeScript
|
|
2628
|
-
const parentType =
|
|
2621
|
+
const parentType = this.getEntityType() as ConnectData["parentType"];
|
|
2629
2622
|
|
|
2630
2623
|
const data: ConnectData = {
|
|
2631
2624
|
childId: this.userId,
|
|
@@ -2680,15 +2673,11 @@ export class BaseEntity<TServerData = any> {
|
|
|
2680
2673
|
const userLink = this._getLinkFromConnectedUser();
|
|
2681
2674
|
|
|
2682
2675
|
if (userLink && (userLink.isInviting || userLink.isAdminInviting)) {
|
|
2683
|
-
const t = this.getEntityType();
|
|
2684
|
-
|
|
2685
2676
|
// 1) Garde runtime pour exclure les types non pris en charge par LinkValidateData
|
|
2686
|
-
|
|
2687
|
-
throw new ApiError(`Le type d'entité "${t}" ne supporte pas cette connexion.`, 400);
|
|
2688
|
-
}
|
|
2677
|
+
this._assertNotEntityType("linkValidate", ["poi", "badges", "news"]);
|
|
2689
2678
|
|
|
2690
2679
|
// 2) Narrow de type pour TypeScript
|
|
2691
|
-
const parentType =
|
|
2680
|
+
const parentType = this.getEntityType() as LinkValidateData["parentType"];
|
|
2692
2681
|
|
|
2693
2682
|
const data: LinkValidateData = {
|
|
2694
2683
|
childId: this.userId,
|
|
@@ -2731,15 +2720,11 @@ export class BaseEntity<TServerData = any> {
|
|
|
2731
2720
|
throw new ApiError("Vous n'êtes pas connecté à cette entité.", 404);
|
|
2732
2721
|
}
|
|
2733
2722
|
|
|
2734
|
-
const t = this.getEntityType();
|
|
2735
|
-
|
|
2736
2723
|
// 1) Garde runtime pour exclure les types non pris en charge par DisconnectData
|
|
2737
|
-
|
|
2738
|
-
throw new ApiError(`Le type d'entité "${t}" ne supporte pas cette connexion.`, 400);
|
|
2739
|
-
}
|
|
2724
|
+
this._assertNotEntityType("disconnect", ["poi", "badges", "news"]);
|
|
2740
2725
|
|
|
2741
2726
|
// 2) Narrow de type pour TypeScript
|
|
2742
|
-
const parentType =
|
|
2727
|
+
const parentType = this.getEntityType() as DisconnectData["parentType"];
|
|
2743
2728
|
|
|
2744
2729
|
const data: DisconnectData = {
|
|
2745
2730
|
childId: this.userId,
|
|
@@ -2791,11 +2776,8 @@ export class BaseEntity<TServerData = any> {
|
|
|
2791
2776
|
}
|
|
2792
2777
|
|
|
2793
2778
|
// Réduit le type de l'entité aux seuls autorisés par UpdateSettingsData
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_SETTINGS.`, 400);
|
|
2797
|
-
}
|
|
2798
|
-
const typeEntity = t as UpdateSettingsData["typeEntity"];
|
|
2779
|
+
this._assertNotEntityType("updateSettings", ["poi", "badges", "news"]);
|
|
2780
|
+
const typeEntity = this.getEntityType() as UpdateSettingsData["typeEntity"];
|
|
2799
2781
|
|
|
2800
2782
|
// Garde runtime pour s'assurer que 'type' et 'value' sont bien fournis
|
|
2801
2783
|
const { type, value } = data;
|
|
@@ -2829,11 +2811,8 @@ export class BaseEntity<TServerData = any> {
|
|
|
2829
2811
|
}
|
|
2830
2812
|
|
|
2831
2813
|
// Réduit le type de l'entité aux seuls autorisés par UpdateBlockDescriptionData
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_DESCRIPTION.`, 400);
|
|
2835
|
-
}
|
|
2836
|
-
const typeElement = t as UpdateBlockDescriptionData["typeElement"];
|
|
2814
|
+
this._assertNotEntityType("updateDescription", ["badges", "news"]);
|
|
2815
|
+
const typeElement = this.getEntityType() as UpdateBlockDescriptionData["typeElement"];
|
|
2837
2816
|
|
|
2838
2817
|
const payload: UpdateBlockDescriptionData = {
|
|
2839
2818
|
block: "descriptions",
|
|
@@ -2860,12 +2839,9 @@ export class BaseEntity<TServerData = any> {
|
|
|
2860
2839
|
throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
|
|
2861
2840
|
}
|
|
2862
2841
|
|
|
2863
|
-
// Réduit le type de l'entité aux seuls autorisés par
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_INFO.`, 400);
|
|
2867
|
-
}
|
|
2868
|
-
const typeElement = t as UpdateBlockInfoData["typeElement"];
|
|
2842
|
+
// Réduit le type de l'entité aux seuls autorisés par UpdateBlockInfoData
|
|
2843
|
+
this._assertNotEntityType("updateInfo", ["badges", "news"]);
|
|
2844
|
+
const typeElement = this.getEntityType() as UpdateBlockInfoData["typeElement"];
|
|
2869
2845
|
|
|
2870
2846
|
const payload: UpdateBlockInfoData = {
|
|
2871
2847
|
block: "info",
|
|
@@ -2890,12 +2866,9 @@ export class BaseEntity<TServerData = any> {
|
|
|
2890
2866
|
throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
|
|
2891
2867
|
}
|
|
2892
2868
|
|
|
2893
|
-
// Réduit le type de l'entité aux seuls autorisés par
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_INFO.`, 400);
|
|
2897
|
-
}
|
|
2898
|
-
const typeElement = t as UpdateBlockSocialData["typeElement"];
|
|
2869
|
+
// Réduit le type de l'entité aux seuls autorisés par UpdateBlockSocialData
|
|
2870
|
+
this._assertNotEntityType("updateSocial", ["badges", "news", "poi", "events"]);
|
|
2871
|
+
const typeElement = this.getEntityType() as UpdateBlockSocialData["typeElement"];
|
|
2899
2872
|
|
|
2900
2873
|
const payload: UpdateBlockSocialData = {
|
|
2901
2874
|
block: "network",
|
|
@@ -2960,10 +2933,7 @@ export class BaseEntity<TServerData = any> {
|
|
|
2960
2933
|
}
|
|
2961
2934
|
|
|
2962
2935
|
// Réduit le type de l'entité aux seuls autorisés par UpdateBlockLocalityData
|
|
2963
|
-
|
|
2964
|
-
if (t === "badges" || t === "news" || t === "comments" || t === "answers") {
|
|
2965
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_LOCALITY.`, 400);
|
|
2966
|
-
}
|
|
2936
|
+
this._assertNotEntityType("updateLocality", ["badges", "news", "comments", "answers"]);
|
|
2967
2937
|
|
|
2968
2938
|
// Garde runtime pour s'assurer que 'address' est bien fourni
|
|
2969
2939
|
if (!("address" in data)) {
|
|
@@ -2979,7 +2949,7 @@ export class BaseEntity<TServerData = any> {
|
|
|
2979
2949
|
const addr: UpdateBlockLocalityData["address"] = addrUnknown;
|
|
2980
2950
|
|
|
2981
2951
|
|
|
2982
|
-
const typeElement
|
|
2952
|
+
const typeElement = this.getEntityType() as UpdateBlockLocalityData["typeElement"];
|
|
2983
2953
|
|
|
2984
2954
|
const payload: UpdateBlockLocalityData = {
|
|
2985
2955
|
block: "localities" as const,
|
|
@@ -3007,12 +2977,9 @@ export class BaseEntity<TServerData = any> {
|
|
|
3007
2977
|
throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
|
|
3008
2978
|
}
|
|
3009
2979
|
|
|
3010
|
-
|
|
3011
|
-
if (t === "badges" || t === "news" || t === "poi" || t === "comments") {
|
|
3012
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_LOCALITY.`, 400);
|
|
3013
|
-
}
|
|
2980
|
+
this._assertNotEntityType("updateSlug", ["badges", "news", "poi", "comments"]);
|
|
3014
2981
|
|
|
3015
|
-
const type =
|
|
2982
|
+
const type = this.getEntityType() as CheckData["type"];
|
|
3016
2983
|
|
|
3017
2984
|
try {
|
|
3018
2985
|
await this.endpointApi.check({ block: "info", type, id: this.id, slug });
|
|
@@ -3041,12 +3008,9 @@ export class BaseEntity<TServerData = any> {
|
|
|
3041
3008
|
throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
|
|
3042
3009
|
}
|
|
3043
3010
|
|
|
3044
|
-
|
|
3045
|
-
if (t === "badges" || t === "news" || t === "comments" || t === "answers") {
|
|
3046
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_LOCALITY.`, 400);
|
|
3047
|
-
}
|
|
3011
|
+
this._assertNotEntityType("updateImageProfil", ["badges", "news", "comments", "answers"]);
|
|
3048
3012
|
|
|
3049
|
-
const folder
|
|
3013
|
+
const folder = this.getEntityType() as NonNullable<ProfilImageData["pathParams"]>["folder"];
|
|
3050
3014
|
|
|
3051
3015
|
image = await this._validateImage(image);
|
|
3052
3016
|
|
|
@@ -3071,12 +3035,9 @@ export class BaseEntity<TServerData = any> {
|
|
|
3071
3035
|
throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
|
|
3072
3036
|
}
|
|
3073
3037
|
|
|
3074
|
-
|
|
3075
|
-
if (t === "badges" || t === "news" || t === "comments" || t === "answers") {
|
|
3076
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_LOCALITY.`, 400);
|
|
3077
|
-
}
|
|
3038
|
+
this._assertNotEntityType("updateImageBanner", ["badges", "news", "comments", "answers"]);
|
|
3078
3039
|
|
|
3079
|
-
const folder
|
|
3040
|
+
const folder = this.getEntityType() as NonNullable<ProfilBannerData["pathParams"]>["folder"];
|
|
3080
3041
|
|
|
3081
3042
|
image = await this._validateImage(image);
|
|
3082
3043
|
|
|
@@ -3440,12 +3401,9 @@ export class BaseEntity<TServerData = any> {
|
|
|
3440
3401
|
throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
|
|
3441
3402
|
}
|
|
3442
3403
|
|
|
3443
|
-
|
|
3444
|
-
if (t === "badges" || t === "news" || t === "poi" || t === "events" || t === "comments" || t === "answers") {
|
|
3445
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par GET_NEWS.`, 400);
|
|
3446
|
-
}
|
|
3404
|
+
this._assertNotEntityType("getNews", ["badges", "news", "poi", "events", "comments", "answers"]);
|
|
3447
3405
|
|
|
3448
|
-
const type
|
|
3406
|
+
const type = this.getEntityType() as NonNullable<GetNewsData["pathParams"]>["type"];
|
|
3449
3407
|
|
|
3450
3408
|
const dateLimit = "dateLimit" in data && typeof data.dateLimit === "number" ? { dateLimit: data.dateLimit } : { dateLimit: 0 };
|
|
3451
3409
|
const indexStep = "indexStep" in data && typeof data.indexStep === "number" ? { indexStep: data.indexStep } : { indexStep: 12 };
|
|
@@ -3482,12 +3440,9 @@ export class BaseEntity<TServerData = any> {
|
|
|
3482
3440
|
throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
|
|
3483
3441
|
}
|
|
3484
3442
|
|
|
3485
|
-
|
|
3486
|
-
if (t === "badges" || t === "news" || t === "poi" || t === "events" || t === "comments" || t === "answers") {
|
|
3487
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_LOCALITY.`, 400);
|
|
3488
|
-
}
|
|
3443
|
+
this._assertNotEntityType("getGallery", ["badges", "news", "poi", "events", "comments", "answers"]);
|
|
3489
3444
|
|
|
3490
|
-
const type
|
|
3445
|
+
const type = this.getEntityType() as NonNullable<GetGalleryData["pathParams"]>["type"];
|
|
3491
3446
|
|
|
3492
3447
|
const payload: GetGalleryData = {
|
|
3493
3448
|
pathParams: { type, id: this.id, docType: data.pathParams?.docType || "image" }
|
|
@@ -3538,10 +3493,7 @@ export class BaseEntity<TServerData = any> {
|
|
|
3538
3493
|
return [];
|
|
3539
3494
|
}
|
|
3540
3495
|
|
|
3541
|
-
|
|
3542
|
-
if (t === "badges" || t === "news" || t === "poi" || t === "comments") {
|
|
3543
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par searchMemberAutocomplete.`, 400);
|
|
3544
|
-
}
|
|
3496
|
+
this._assertNotEntityType("searchMembers", ["badges", "news", "poi", "comments"]);
|
|
3545
3497
|
|
|
3546
3498
|
result.forEach(item => {
|
|
3547
3499
|
for (const key of Object.keys(item)) {
|
|
@@ -3701,12 +3653,9 @@ export class BaseEntity<TServerData = any> {
|
|
|
3701
3653
|
throw new ApiError("Utilisateur non connecté.", 401);
|
|
3702
3654
|
}
|
|
3703
3655
|
|
|
3704
|
-
|
|
3705
|
-
if (t === "badges" || t === "news" || t === "poi" || t === "comments") {
|
|
3706
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_LOCALITY.`, 400);
|
|
3707
|
-
}
|
|
3656
|
+
this._assertNotEntityType("follow", ["badges", "news", "poi", "comments"]);
|
|
3708
3657
|
|
|
3709
|
-
const parentType =
|
|
3658
|
+
const parentType = this.getEntityType() as FollowData["parentType"];
|
|
3710
3659
|
|
|
3711
3660
|
const userLink = this.userContext?.serverData?.links?.["follows"]?.[this.id] || null;
|
|
3712
3661
|
|
|
@@ -3748,12 +3697,9 @@ export class BaseEntity<TServerData = any> {
|
|
|
3748
3697
|
|
|
3749
3698
|
const userLink = this.userContext?.serverData?.links?.["follows"]?.[this.id] || null;
|
|
3750
3699
|
|
|
3751
|
-
|
|
3752
|
-
if (t === "badges" || t === "news" || t === "poi") {
|
|
3753
|
-
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par UPDATE_BLOCK_LOCALITY.`, 400);
|
|
3754
|
-
}
|
|
3700
|
+
this._assertNotEntityType("unfollow", ["badges", "news", "poi"]);
|
|
3755
3701
|
|
|
3756
|
-
const parentType =
|
|
3702
|
+
const parentType = this.getEntityType() as DisconnectData["parentType"];
|
|
3757
3703
|
|
|
3758
3704
|
if (userLink) {
|
|
3759
3705
|
const data: DisconnectData = {
|
|
@@ -3816,6 +3762,52 @@ export class BaseEntity<TServerData = any> {
|
|
|
3816
3762
|
}
|
|
3817
3763
|
}
|
|
3818
3764
|
|
|
3765
|
+
/**
|
|
3766
|
+
* Vérifie que l'entité N'EST PAS d'un type spécifique.
|
|
3767
|
+
*
|
|
3768
|
+
* @param methodName - Nom de la méthode (pour le message d'erreur).
|
|
3769
|
+
* @param excludedTypes - Types d'entité NON supportés (arguments individuels ou tableau).
|
|
3770
|
+
* @throws {ApiError} - Si l'entité est d'un type exclu.
|
|
3771
|
+
* @protected
|
|
3772
|
+
* @example
|
|
3773
|
+
* this._assertNotEntityType("method", "poi", "badges", "news");
|
|
3774
|
+
* this._assertNotEntityType("method", ["poi", "badges", "news"]);
|
|
3775
|
+
*/
|
|
3776
|
+
protected _assertNotEntityType(methodName: string, ...excludedTypes: (string | string[])[]): void {
|
|
3777
|
+
const types = Array.isArray(excludedTypes[0]) ? excludedTypes[0] : excludedTypes as string[];
|
|
3778
|
+
const t = this.getEntityType();
|
|
3779
|
+
if (types.includes(t)) {
|
|
3780
|
+
throw new ApiError(`Le type d'entité "${t}" n'est pas supporté par ${methodName}.`, 400);
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3784
|
+
/**
|
|
3785
|
+
* Valide les préconditions et retourne le lien utilisateur.
|
|
3786
|
+
*
|
|
3787
|
+
* @param methodName - Nom de la méthode appelante (pour les messages d'erreur).
|
|
3788
|
+
* @param expectedTypes - Types d'entité autorisés.
|
|
3789
|
+
* @param options - Options de validation.
|
|
3790
|
+
* @param options.silent - Si `true`, retourne `null` au lieu de lever une exception. Par défaut `true`.
|
|
3791
|
+
* @returns - Le lien de l'utilisateur connecté avec l'entité, ou `null` si validation échoue.
|
|
3792
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3793
|
+
* @protected
|
|
3794
|
+
*/
|
|
3795
|
+
protected _getValidatedUserLink(
|
|
3796
|
+
methodName: string,
|
|
3797
|
+
expectedTypes: string[],
|
|
3798
|
+
options?: { silent?: boolean }
|
|
3799
|
+
): MinimalUserLink | null {
|
|
3800
|
+
const silent = options?.silent ?? true;
|
|
3801
|
+
try {
|
|
3802
|
+
this._checkAccess(methodName);
|
|
3803
|
+
this._assertEntityType(...expectedTypes);
|
|
3804
|
+
} catch (e) {
|
|
3805
|
+
if (silent) return null;
|
|
3806
|
+
throw e;
|
|
3807
|
+
}
|
|
3808
|
+
return this._getLinkFromConnectedUser();
|
|
3809
|
+
}
|
|
3810
|
+
|
|
3819
3811
|
/**
|
|
3820
3812
|
* Vérifie si l'entité est liée à un type de lien spécifique.
|
|
3821
3813
|
*
|
|
@@ -3862,22 +3854,24 @@ export class BaseEntity<TServerData = any> {
|
|
|
3862
3854
|
*
|
|
3863
3855
|
* @param options - Options de vérification.
|
|
3864
3856
|
* @param options.checkHierarchy - Si `true`, vérifie également si l'utilisateur est admin via la hiérarchie parent. Par défaut `false`.
|
|
3857
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3865
3858
|
* @returns - `true` si l'utilisateur est administrateur, `false` sinon.
|
|
3866
|
-
* @throws {ApiError}
|
|
3859
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3867
3860
|
*/
|
|
3868
|
-
isAdmin(options?: { checkHierarchy?: boolean }): boolean {
|
|
3869
|
-
this.
|
|
3870
|
-
|
|
3861
|
+
isAdmin(options?: { checkHierarchy?: boolean; silent?: boolean }): boolean {
|
|
3862
|
+
const userLink = this._getValidatedUserLink(
|
|
3863
|
+
"vérifier l'administrateur",
|
|
3864
|
+
["organizations", "projects", "events"],
|
|
3865
|
+
{ silent: options?.silent }
|
|
3866
|
+
);
|
|
3871
3867
|
|
|
3872
3868
|
// 1. Vérifier lien direct sur l'entité courante
|
|
3873
|
-
const userLink = this._getLinkFromConnectedUser();
|
|
3874
3869
|
if (this._validateUserLink(userLink) && userLink?.isAdmin === true && !userLink?.isAdminPending) {
|
|
3875
3870
|
return true;
|
|
3876
3871
|
}
|
|
3877
3872
|
|
|
3878
3873
|
// 2. Si pas de lien direct, remonter la hiérarchie parent (si activé)
|
|
3879
|
-
|
|
3880
|
-
if (checkHierarchy) {
|
|
3874
|
+
if (options?.checkHierarchy) {
|
|
3881
3875
|
return this._isAdminViaHierarchy();
|
|
3882
3876
|
}
|
|
3883
3877
|
|
|
@@ -3887,131 +3881,172 @@ export class BaseEntity<TServerData = any> {
|
|
|
3887
3881
|
/**
|
|
3888
3882
|
* Vérifie si l'utilisateur est soit l'auteur, soit administrateur de l'entité.
|
|
3889
3883
|
*
|
|
3884
|
+
* @param options - Options de vérification.
|
|
3885
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3890
3886
|
* @returns - `true` si l'utilisateur est l'auteur ou administrateur, `false` sinon.
|
|
3891
|
-
* @throws {ApiError}
|
|
3887
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3892
3888
|
*/
|
|
3893
|
-
isAuthorOrAdmin(): boolean {
|
|
3894
|
-
this.
|
|
3895
|
-
return this.isAuthor() || this.isAdmin();
|
|
3889
|
+
isAuthorOrAdmin(options?: { silent?: boolean }): boolean {
|
|
3890
|
+
return this.isAuthor() || this.isAdmin(options);
|
|
3896
3891
|
}
|
|
3897
3892
|
|
|
3898
3893
|
/**
|
|
3899
3894
|
* Vérifie si l'utilisateur est membre de l'entité.
|
|
3900
3895
|
*
|
|
3896
|
+
* @param options - Options de vérification.
|
|
3897
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3901
3898
|
* @returns - `true` si l'utilisateur est membre, `false` sinon.
|
|
3902
|
-
* @throws {ApiError}
|
|
3899
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3903
3900
|
*/
|
|
3904
|
-
isMember(): boolean {
|
|
3905
|
-
this.
|
|
3906
|
-
|
|
3907
|
-
|
|
3901
|
+
isMember(options?: { silent?: boolean }): boolean {
|
|
3902
|
+
const userLink = this._getValidatedUserLink(
|
|
3903
|
+
"vérifier le membre",
|
|
3904
|
+
["organizations"],
|
|
3905
|
+
{ silent: options?.silent }
|
|
3906
|
+
);
|
|
3908
3907
|
return this._validateUserLink(userLink);
|
|
3909
3908
|
}
|
|
3910
3909
|
|
|
3911
3910
|
/**
|
|
3912
3911
|
* Vérifie si l'utilisateur est contributeur de l'entité.
|
|
3913
3912
|
*
|
|
3913
|
+
* @param options - Options de vérification.
|
|
3914
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3914
3915
|
* @returns - `true` si l'utilisateur est contributeur, `false` sinon.
|
|
3915
|
-
* @throws {ApiError}
|
|
3916
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3916
3917
|
*/
|
|
3917
|
-
isContributor(): boolean {
|
|
3918
|
-
this.
|
|
3919
|
-
|
|
3920
|
-
|
|
3918
|
+
isContributor(options?: { silent?: boolean }): boolean {
|
|
3919
|
+
const userLink = this._getValidatedUserLink(
|
|
3920
|
+
"vérifier le contributeur",
|
|
3921
|
+
["projects"],
|
|
3922
|
+
{ silent: options?.silent }
|
|
3923
|
+
);
|
|
3921
3924
|
return this._validateUserLink(userLink);
|
|
3922
3925
|
}
|
|
3923
3926
|
|
|
3924
3927
|
/**
|
|
3925
3928
|
* Vérifie si l'utilisateur est participant de l'entité.
|
|
3926
3929
|
*
|
|
3930
|
+
* @param options - Options de vérification.
|
|
3931
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3927
3932
|
* @returns - `true` si l'utilisateur est participant, `false` sinon.
|
|
3928
|
-
* @throws {ApiError}
|
|
3933
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3929
3934
|
*/
|
|
3930
|
-
isAttendee(): boolean {
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3935
|
+
isAttendee(options?: { silent?: boolean }): boolean {
|
|
3936
|
+
const userLink = this._getValidatedUserLink(
|
|
3937
|
+
"vérifier le participant",
|
|
3938
|
+
["events"],
|
|
3939
|
+
{ silent: options?.silent }
|
|
3940
|
+
);
|
|
3934
3941
|
return this._validateUserLink(userLink);
|
|
3935
3942
|
}
|
|
3936
3943
|
|
|
3937
3944
|
/**
|
|
3938
3945
|
* Vérifie si l'utilisateur suit l'entité.
|
|
3939
3946
|
*
|
|
3947
|
+
* @param options - Options de vérification.
|
|
3948
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3940
3949
|
* @returns - `true` si l'utilisateur suit l'entité, `false` sinon.
|
|
3941
|
-
* @throws {ApiError}
|
|
3950
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3942
3951
|
*/
|
|
3943
|
-
isFollower(): boolean {
|
|
3944
|
-
|
|
3945
|
-
|
|
3952
|
+
isFollower(options?: { silent?: boolean }): boolean {
|
|
3953
|
+
const userLink = this._getValidatedUserLink(
|
|
3954
|
+
"vérifier si il vous suit",
|
|
3955
|
+
["citoyens", "organizations", "projects", "events", "poi"],
|
|
3956
|
+
{ silent: options?.silent }
|
|
3957
|
+
);
|
|
3958
|
+
if (!userLink) return false;
|
|
3946
3959
|
return this._isLinked("followers");
|
|
3947
3960
|
}
|
|
3948
3961
|
|
|
3949
3962
|
/**
|
|
3950
3963
|
* Vérifie si l'utilisateur est abonné à l'entité.
|
|
3951
3964
|
*
|
|
3965
|
+
* @param options - Options de vérification.
|
|
3966
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3952
3967
|
* @returns - `true` si l'utilisateur est abonné, `false` sinon.
|
|
3953
|
-
* @throws {ApiError}
|
|
3968
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3954
3969
|
*/
|
|
3955
|
-
isFollowing(): boolean {
|
|
3956
|
-
|
|
3957
|
-
|
|
3970
|
+
isFollowing(options?: { silent?: boolean }): boolean {
|
|
3971
|
+
const userLink = this._getValidatedUserLink(
|
|
3972
|
+
"vérifier si vous le suivez",
|
|
3973
|
+
["citoyens", "organizations", "projects", "events", "poi"],
|
|
3974
|
+
{ silent: options?.silent }
|
|
3975
|
+
);
|
|
3976
|
+
if (!userLink) return false;
|
|
3958
3977
|
return this._isLinked("follows");
|
|
3959
3978
|
}
|
|
3960
3979
|
|
|
3961
3980
|
/**
|
|
3962
3981
|
* Vérifie si le lien de l'utilisateur connecté est en attente de validation.
|
|
3963
3982
|
*
|
|
3983
|
+
* @param options - Options de vérification.
|
|
3984
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3964
3985
|
* @returns - `true` si le lien est à valider, `false` sinon.
|
|
3965
|
-
* @throws {ApiError}
|
|
3986
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3966
3987
|
*/
|
|
3967
|
-
isToBeValidated(): boolean {
|
|
3968
|
-
this.
|
|
3969
|
-
|
|
3970
|
-
|
|
3988
|
+
isToBeValidated(options?: { silent?: boolean }): boolean {
|
|
3989
|
+
const userLink = this._getValidatedUserLink(
|
|
3990
|
+
"vérifier si il est à valider",
|
|
3991
|
+
["citoyens", "organizations", "projects", "events"],
|
|
3992
|
+
{ silent: options?.silent }
|
|
3993
|
+
);
|
|
3971
3994
|
if (!userLink) return false;
|
|
3972
|
-
return userLink
|
|
3995
|
+
return userLink.toBeValidated === true;
|
|
3973
3996
|
}
|
|
3974
3997
|
|
|
3975
3998
|
/**
|
|
3976
3999
|
* Vérifie si l'utilisateur connecté a été invité à rejoindre l'entité.
|
|
3977
4000
|
*
|
|
4001
|
+
* @param options - Options de vérification.
|
|
4002
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3978
4003
|
* @returns - `true` si l'utilisateur est invité, `false` sinon.
|
|
3979
|
-
* @throws {ApiError}
|
|
4004
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3980
4005
|
*/
|
|
3981
|
-
isInviting(): boolean {
|
|
3982
|
-
this.
|
|
3983
|
-
|
|
3984
|
-
|
|
4006
|
+
isInviting(options?: { silent?: boolean }): boolean {
|
|
4007
|
+
const userLink = this._getValidatedUserLink(
|
|
4008
|
+
"vérifier si il est invité",
|
|
4009
|
+
["citoyens", "organizations", "projects", "events"],
|
|
4010
|
+
{ silent: options?.silent }
|
|
4011
|
+
);
|
|
3985
4012
|
if (!userLink) return false;
|
|
3986
|
-
return userLink
|
|
4013
|
+
return userLink.isInviting === true;
|
|
3987
4014
|
}
|
|
3988
4015
|
|
|
3989
4016
|
/**
|
|
3990
4017
|
* Vérifie si l'utilisateur connecté a été invité en tant qu'administrateur.
|
|
3991
4018
|
*
|
|
4019
|
+
* @param options - Options de vérification.
|
|
4020
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
3992
4021
|
* @returns - `true` si l'utilisateur est invité admin, `false` sinon.
|
|
3993
|
-
* @throws {ApiError}
|
|
4022
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
3994
4023
|
*/
|
|
3995
|
-
isInvitingAdmin(): boolean {
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
4024
|
+
isInvitingAdmin(options?: { silent?: boolean }): boolean {
|
|
4025
|
+
const userLink = this._getValidatedUserLink(
|
|
4026
|
+
"vérifier si il est invité admin",
|
|
4027
|
+
["organizations", "projects", "events"],
|
|
4028
|
+
{ silent: options?.silent }
|
|
4029
|
+
);
|
|
3999
4030
|
if (!userLink) return false;
|
|
4000
|
-
return (userLink
|
|
4031
|
+
return (userLink.isAdminInviting === true || userLink.isInviting === true) && userLink.isAdmin === true;
|
|
4001
4032
|
}
|
|
4002
4033
|
|
|
4003
4034
|
/**
|
|
4004
4035
|
* Vérifie si l'utilisateur connecté est administrateur en attente de confirmation.
|
|
4005
4036
|
*
|
|
4037
|
+
* @param options - Options de vérification.
|
|
4038
|
+
* @param options.silent - Si `true`, retourne `false` au lieu de lever une exception. Par défaut `true`.
|
|
4006
4039
|
* @returns - `true` si l'utilisateur est admin en attente, `false` sinon.
|
|
4007
|
-
* @throws {ApiError}
|
|
4040
|
+
* @throws {ApiError} - Si `silent` est `false` et que les préconditions ne sont pas remplies.
|
|
4008
4041
|
*/
|
|
4009
|
-
isAdminPending(): boolean {
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4042
|
+
isAdminPending(options?: { silent?: boolean }): boolean {
|
|
4043
|
+
const userLink = this._getValidatedUserLink(
|
|
4044
|
+
"vérifier si il est en attente admin",
|
|
4045
|
+
["organizations", "projects", "events"],
|
|
4046
|
+
{ silent: options?.silent }
|
|
4047
|
+
);
|
|
4013
4048
|
if (!userLink) return false;
|
|
4014
|
-
return userLink
|
|
4049
|
+
return userLink.isAdmin === true && userLink.isAdminPending === true;
|
|
4015
4050
|
}
|
|
4016
4051
|
|
|
4017
4052
|
/**
|
package/src/api/Event.ts
CHANGED
|
@@ -14,10 +14,6 @@ export class Event extends BaseEntity<EventItemNormalized> {
|
|
|
14
14
|
|
|
15
15
|
static override SCHEMA_CONSTANTS: string[] = [
|
|
16
16
|
"ADD_EVENT",
|
|
17
|
-
// "UPDATE_BLOCK_DESCRIPTION",
|
|
18
|
-
// "UPDATE_BLOCK_INFO",
|
|
19
|
-
// "UPDATE_BLOCK_SOCIAL",
|
|
20
|
-
// "UPDATE_BLOCK_LOCALITY",
|
|
21
17
|
"UPDATE_BLOCK_SLUG",
|
|
22
18
|
"PROFIL_IMAGE"
|
|
23
19
|
];
|
|
@@ -28,10 +24,6 @@ export class Event extends BaseEntity<EventItemNormalized> {
|
|
|
28
24
|
] as const);
|
|
29
25
|
|
|
30
26
|
static UPDATE_BLOCKS = new Map([
|
|
31
|
-
// ["UPDATE_BLOCK_DESCRIPTION", "updateDescription"],
|
|
32
|
-
// ["UPDATE_BLOCK_SOCIAL", "updateSocial"],
|
|
33
|
-
// ["UPDATE_BLOCK_LOCALITY", "updateLocality"],
|
|
34
|
-
// ["UPDATE_BLOCK_INFO", "updateInfo"],
|
|
35
27
|
["UPDATE_BLOCK_SLUG", "updateSlug"],
|
|
36
28
|
["PROFIL_IMAGE", "updateImageProfil"]
|
|
37
29
|
] as const);
|
package/src/api/Organization.ts
CHANGED
|
@@ -500,6 +500,16 @@ export class Organization extends BaseEntity<OrganizationItemNormalized> {
|
|
|
500
500
|
return super.acceptInvitation();
|
|
501
501
|
}
|
|
502
502
|
|
|
503
|
+
/**
|
|
504
|
+
* {@inheritDoc BaseEntity#requestPromoteToAdmin}
|
|
505
|
+
*
|
|
506
|
+
* Envoie une demande de promotion en tant qu'administrateur de l'organisation.
|
|
507
|
+
* L'utilisateur doit déjà être membre de l'organisation.
|
|
508
|
+
*/
|
|
509
|
+
override requestPromoteToAdmin() {
|
|
510
|
+
return super.requestPromoteToAdmin();
|
|
511
|
+
}
|
|
512
|
+
|
|
503
513
|
/**
|
|
504
514
|
* {@inheritDoc BaseEntity#leave}
|
|
505
515
|
*
|
package/src/api/Project.ts
CHANGED
|
@@ -378,6 +378,16 @@ export class Project extends BaseEntity<ProjectItemNormalized> {
|
|
|
378
378
|
return super.acceptInvitation();
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
+
/**
|
|
382
|
+
* {@inheritDoc BaseEntity#requestPromoteToAdmin}
|
|
383
|
+
*
|
|
384
|
+
* Envoie une demande de promotion en tant qu'administrateur du projet.
|
|
385
|
+
* L'utilisateur doit déjà être contributeur du projet.
|
|
386
|
+
*/
|
|
387
|
+
override requestPromoteToAdmin() {
|
|
388
|
+
return super.requestPromoteToAdmin();
|
|
389
|
+
}
|
|
390
|
+
|
|
381
391
|
/**
|
|
382
392
|
* {@inheritDoc BaseEntity#leave}
|
|
383
393
|
*
|