@communecter/cocolight-api-client 1.0.54 → 1.0.56

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.
Files changed (179) hide show
  1. package/dist/401.cocolight-api-client.browser.js +1 -0
  2. package/dist/401.cocolight-api-client.cjs +1 -0
  3. package/dist/401.cocolight-api-client.mjs.js +1 -0
  4. package/dist/588.cocolight-api-client.browser.js +1 -0
  5. package/dist/588.cocolight-api-client.cjs +1 -0
  6. package/dist/588.cocolight-api-client.mjs.js +1 -0
  7. package/dist/593.cocolight-api-client.browser.js +1 -0
  8. package/dist/593.cocolight-api-client.cjs +1 -0
  9. package/dist/593.cocolight-api-client.mjs.js +1 -0
  10. package/dist/839.cocolight-api-client.browser.js +1 -0
  11. package/dist/839.cocolight-api-client.cjs +1 -0
  12. package/dist/839.cocolight-api-client.mjs.js +1 -0
  13. package/dist/cocolight-api-client.browser.js +3 -3
  14. package/dist/cocolight-api-client.cjs +1 -1
  15. package/dist/cocolight-api-client.mjs.js +1 -1
  16. package/dist/cocolight-api-client.vite.mjs.js +1 -1
  17. package/dist/cocolight-api-client.vite.mjs.js.map +1 -1
  18. package/package.json +29 -17
  19. package/src/{Api.js → Api.ts} +85 -95
  20. package/src/{ApiClient.js → ApiClient.ts} +436 -247
  21. package/src/EJSONType.ts +103 -0
  22. package/src/api/{Badge.js → Badge.ts} +56 -45
  23. package/src/api/BaseEntity.ts +3890 -0
  24. package/src/api/Comment.ts +200 -0
  25. package/src/api/{EndpointApi.js → EndpointApi.ts} +363 -297
  26. package/src/api/EndpointApi.types.ts +4609 -0
  27. package/src/api/EntityRegistry.ts +203 -0
  28. package/src/api/Event.ts +332 -0
  29. package/src/api/News.ts +331 -0
  30. package/src/api/{Organization.js → Organization.ts} +155 -119
  31. package/src/api/{Poi.js → Poi.ts} +68 -60
  32. package/src/api/{Project.js → Project.ts} +150 -127
  33. package/src/api/{User.js → User.ts} +321 -256
  34. package/src/api/UserApi.ts +148 -0
  35. package/src/api/serverDataType/Comment.ts +88 -0
  36. package/src/api/serverDataType/Event.ts +80 -0
  37. package/src/api/serverDataType/News.ts +138 -0
  38. package/src/api/serverDataType/Organization.ts +80 -0
  39. package/src/api/serverDataType/Project.ts +71 -0
  40. package/src/api/serverDataType/User.ts +103 -0
  41. package/src/api/serverDataType/common.ts +80 -0
  42. package/src/endpoints.module.ts +2621 -0
  43. package/src/error.ts +86 -0
  44. package/src/index.ts +86 -0
  45. package/src/mixin/UserMixin.ts +4 -0
  46. package/src/types/api-responses.ts +217 -0
  47. package/src/types/entities.ts +22 -0
  48. package/src/types/error-guards.ts +230 -0
  49. package/src/types/index.ts +39 -0
  50. package/src/types/payloads.ts +21 -0
  51. package/src/types/transforms.ts +110 -0
  52. package/src/utils/{FileOfflineStorageStrategy.node.js → FileOfflineStorageStrategy.node.ts} +15 -12
  53. package/src/utils/{FileStorageStrategy.node.js → FileStorageStrategy.node.ts} +16 -39
  54. package/src/utils/MultiServerFileStorageStrategy.node.ts +67 -0
  55. package/src/utils/MultiServerTokenStorageStrategy.ts +139 -0
  56. package/src/utils/{OfflineClientManager.js → OfflineClientManager.ts} +82 -86
  57. package/src/utils/OfflineQueueStorageStrategy.ts +47 -0
  58. package/src/utils/TokenStorage.ts +77 -0
  59. package/src/utils/compat.ts +12 -0
  60. package/src/utils/createDefaultMultiServerTokenStorageStrategy.ts +35 -0
  61. package/src/utils/{createDefaultOfflineStrategy.js → createDefaultOfflineStrategy.ts} +8 -3
  62. package/src/utils/createDefaultTokenStorageStrategy.ts +33 -0
  63. package/src/utils/{reactive.js → reactive.ts} +49 -40
  64. package/src/utils/stream-utils.node.ts +12 -0
  65. package/types/Api.d.ts +38 -82
  66. package/types/Api.d.ts.map +1 -0
  67. package/types/ApiClient.d.ts +244 -184
  68. package/types/ApiClient.d.ts.map +1 -0
  69. package/types/EJSONType.d.ts +48 -22
  70. package/types/EJSONType.d.ts.map +1 -0
  71. package/types/api/Badge.d.ts +20 -20
  72. package/types/api/Badge.d.ts.map +1 -0
  73. package/types/api/BaseEntity.d.ts +751 -446
  74. package/types/api/BaseEntity.d.ts.map +1 -0
  75. package/types/api/Comment.d.ts +36 -0
  76. package/types/api/EndpointApi.d.ts +347 -295
  77. package/types/api/EndpointApi.d.ts.map +1 -0
  78. package/types/api/EndpointApi.types.d.ts +3914 -4133
  79. package/types/api/EntityRegistry.d.ts +18 -16
  80. package/types/api/EntityRegistry.d.ts.map +1 -0
  81. package/types/api/Event.d.ts +119 -35
  82. package/types/api/Event.d.ts.map +1 -0
  83. package/types/api/News.d.ts +52 -20
  84. package/types/api/News.d.ts.map +1 -0
  85. package/types/api/Organization.d.ts +165 -49
  86. package/types/api/Organization.d.ts.map +1 -0
  87. package/types/api/Poi.d.ts +51 -22
  88. package/types/api/Poi.d.ts.map +1 -0
  89. package/types/api/Project.d.ts +151 -52
  90. package/types/api/Project.d.ts.map +1 -0
  91. package/types/api/User.d.ts +222 -93
  92. package/types/api/User.d.ts.map +1 -0
  93. package/types/api/UserApi.d.ts +60 -9
  94. package/types/api/UserApi.d.ts.map +1 -0
  95. package/types/api/serverDataType/Comment.d.ts +83 -0
  96. package/types/api/serverDataType/Event.d.ts +67 -0
  97. package/types/api/serverDataType/News.d.ts +130 -0
  98. package/types/api/serverDataType/Organization.d.ts +65 -0
  99. package/types/api/serverDataType/Organization.d.ts.map +1 -0
  100. package/types/api/serverDataType/Project.d.ts +58 -0
  101. package/types/api/serverDataType/Project.d.ts.map +1 -0
  102. package/types/api/serverDataType/User.d.ts +86 -0
  103. package/types/api/serverDataType/User.d.ts.map +1 -0
  104. package/types/api/serverDataType/common.d.ts +71 -0
  105. package/types/api/serverDataType/common.d.ts.map +1 -0
  106. package/types/endpoints.module.d.ts +6922 -1215
  107. package/types/endpoints.module.d.ts.map +1 -0
  108. package/types/error.d.ts +25 -51
  109. package/types/error.d.ts.map +1 -0
  110. package/types/index.d.ts +55 -48
  111. package/types/index.d.ts.map +1 -0
  112. package/types/mixin/UserMixin.d.ts +1 -1
  113. package/types/mixin/UserMixin.d.ts.map +1 -0
  114. package/types/types/api-responses.d.ts +190 -0
  115. package/types/types/api-responses.d.ts.map +1 -0
  116. package/types/types/entities.d.ts +17 -0
  117. package/types/types/entities.d.ts.map +1 -0
  118. package/types/types/error-guards.d.ts +99 -0
  119. package/types/types/error-guards.d.ts.map +1 -0
  120. package/types/types/index.d.ts +7 -0
  121. package/types/types/payloads.d.ts +17 -0
  122. package/types/types/payloads.d.ts.map +1 -0
  123. package/types/types/transforms.d.ts +79 -0
  124. package/types/types/transforms.d.ts.map +1 -0
  125. package/types/utils/FileOfflineStorageStrategy.node.d.ts +10 -9
  126. package/types/utils/FileOfflineStorageStrategy.node.d.ts.map +1 -0
  127. package/types/utils/FileStorageStrategy.node.d.ts +9 -20
  128. package/types/utils/FileStorageStrategy.node.d.ts.map +1 -0
  129. package/types/utils/MultiServerFileStorageStrategy.node.d.ts +13 -18
  130. package/types/utils/MultiServerFileStorageStrategy.node.d.ts.map +1 -0
  131. package/types/utils/MultiServerTokenStorageStrategy.d.ts +30 -51
  132. package/types/utils/MultiServerTokenStorageStrategy.d.ts.map +1 -0
  133. package/types/utils/OfflineClientManager.d.ts +52 -88
  134. package/types/utils/OfflineClientManager.d.ts.map +1 -0
  135. package/types/utils/OfflineQueueStorageStrategy.d.ts +12 -9
  136. package/types/utils/OfflineQueueStorageStrategy.d.ts.map +1 -0
  137. package/types/utils/TokenStorage.d.ts +20 -70
  138. package/types/utils/TokenStorage.d.ts.map +1 -0
  139. package/types/utils/compat.d.ts +4 -0
  140. package/types/utils/compat.d.ts.map +1 -0
  141. package/types/utils/createDefaultMultiServerTokenStorageStrategy.d.ts +2 -11
  142. package/types/utils/createDefaultMultiServerTokenStorageStrategy.d.ts.map +1 -0
  143. package/types/utils/createDefaultOfflineStrategy.d.ts +2 -3
  144. package/types/utils/createDefaultOfflineStrategy.d.ts.map +1 -0
  145. package/types/utils/createDefaultTokenStorageStrategy.d.ts +2 -12
  146. package/types/utils/createDefaultTokenStorageStrategy.d.ts.map +1 -0
  147. package/types/utils/reactive.d.ts +10 -16
  148. package/types/utils/reactive.d.ts.map +1 -0
  149. package/types/utils/stream-utils.node.d.ts +3 -2
  150. package/types/utils/stream-utils.node.d.ts.map +1 -0
  151. package/dist/123.cocolight-api-client.browser.js +0 -1
  152. package/dist/123.cocolight-api-client.cjs +0 -1
  153. package/dist/22.cocolight-api-client.mjs.js +0 -1
  154. package/dist/339.cocolight-api-client.mjs.js +0 -1
  155. package/dist/394.cocolight-api-client.browser.js +0 -1
  156. package/dist/394.cocolight-api-client.cjs +0 -1
  157. package/dist/405.cocolight-api-client.browser.js +0 -1
  158. package/dist/405.cocolight-api-client.cjs +0 -1
  159. package/dist/774.cocolight-api-client.mjs.js +0 -1
  160. package/dist/790.cocolight-api-client.mjs.js +0 -1
  161. package/dist/931.cocolight-api-client.browser.js +0 -1
  162. package/dist/931.cocolight-api-client.cjs +0 -1
  163. package/src/EJSONType.js +0 -53
  164. package/src/api/BaseEntity.js +0 -2828
  165. package/src/api/EntityRegistry.js +0 -152
  166. package/src/api/Event.js +0 -226
  167. package/src/api/News.js +0 -244
  168. package/src/api/UserApi.js +0 -81
  169. package/src/endpoints.module.js +0 -5
  170. package/src/error.js +0 -121
  171. package/src/index.js +0 -97
  172. package/src/mixin/UserMixin.js +0 -8
  173. package/src/utils/MultiServerFileStorageStrategy.node.js +0 -87
  174. package/src/utils/MultiServerTokenStorageStrategy.js +0 -188
  175. package/src/utils/OfflineQueueStorageStrategy.js +0 -51
  176. package/src/utils/TokenStorage.js +0 -153
  177. package/src/utils/createDefaultMultiServerTokenStorageStrategy.js +0 -51
  178. package/src/utils/createDefaultTokenStorageStrategy.js +0 -49
  179. package/src/utils/stream-utils.node.js +0 -10
@@ -1,15 +1,34 @@
1
1
  import { ApiError } from "../error.js";
2
- import BaseEntity from "./BaseEntity.js";
2
+ import { BaseEntity } from "./BaseEntity.js";
3
3
  import { UserMixin } from "../mixin/UserMixin.js";
4
4
 
5
- // User.js
6
- export class User extends BaseEntity {
7
-
8
- static entityType = "citoyens";
9
-
10
- static entityTag = "User";
11
-
12
- static SCHEMA_CONSTANTS = [
5
+ import type { Badge } from "./Badge.js";
6
+ import type { PaginatorPage } from "./BaseEntity.js";
7
+ import type {
8
+ ConnectData,
9
+ DisconnectData,
10
+ LinkValidateData,
11
+ FollowData,
12
+ ChangePasswordData,
13
+ DeleteAccountData,
14
+ GetSubscriptionsAdminData,
15
+ GetSubscriptionsData,
16
+ GetOrganizationsNoAdminData,
17
+ GetOrganizationsAdminData,
18
+ GetFriendsAdminData
19
+ } from "./EndpointApi.types.js";
20
+ import type { Organization } from "./Organization.js";
21
+
22
+ type ApiClient = import("../ApiClient.js").default;
23
+ type UserItemNormalized = import("./serverDataType/User.js").UserItemNormalized;
24
+
25
+ export class User extends BaseEntity<UserItemNormalized> {
26
+
27
+ static override entityType = "citoyens" as const;
28
+
29
+ static override entityTag = "User";
30
+
31
+ static override SCHEMA_CONSTANTS: string[] = [
13
32
  "UPDATE_BLOCK_DESCRIPTION",
14
33
  "UPDATE_BLOCK_INFO",
15
34
  "UPDATE_BLOCK_SOCIAL",
@@ -25,70 +44,92 @@ export class User extends BaseEntity {
25
44
  ["UPDATE_BLOCK_INFO", "updateInfo"],
26
45
  ["UPDATE_BLOCK_SLUG", "updateSlug"],
27
46
  ["PROFIL_IMAGE", "updateImageProfil"]
28
- ]);
47
+ ] as const);
29
48
 
30
- defaultFields = {
31
- typeElement: this.getEntityType(),
49
+ override defaultFields: Record<string, any> = {
50
+ typeElement: this.getEntityType(),
32
51
  };
33
-
34
- removeFields = [
52
+
53
+ override removeFields: string[] = [
35
54
  "typeElement",
36
55
  ];
37
-
38
- transforms = {
39
- github: (val, full) => full?.socialNetwork?.github,
40
- gitlab: (val, full) => full?.socialNetwork?.gitlab,
41
- facebook: (val, full) => full?.socialNetwork?.facebook,
42
- twitter: (val, full) => full?.socialNetwork?.twitter,
43
- instagram: (val, full) => full?.socialNetwork?.instagram,
44
- diaspora: (val, full) => full?.socialNetwork?.diaspora,
45
- mastodon: (val, full) => full?.socialNetwork?.mastodon,
46
- telegram: (val, full) => full?.socialNetwork?.telegram,
47
- signal: (val, full) => full?.socialNetwork?.signal
48
- };
56
+
57
+ override transforms: {
58
+ github: (val: any, full: any) => any;
59
+ gitlab: (val: any, full: any) => any;
60
+ facebook: (val: any, full: any) => any;
61
+ twitter: (val: any, full: any) => any;
62
+ instagram: (val: any, full: any) => any;
63
+ diaspora: (val: any, full: any) => any;
64
+ mastodon: (val: any, full: any) => any;
65
+ telegram: (val: any, full: any) => any;
66
+ signal: (val: any, full: any) => any;
67
+ } = {
68
+ github: (val, full) => full?.socialNetwork?.github,
69
+ gitlab: (val, full) => full?.socialNetwork?.gitlab,
70
+ facebook: (val, full) => full?.socialNetwork?.facebook,
71
+ twitter: (val, full) => full?.socialNetwork?.twitter,
72
+ instagram: (val, full) => full?.socialNetwork?.instagram,
73
+ diaspora: (val, full) => full?.socialNetwork?.diaspora,
74
+ mastodon: (val, full) => full?.socialNetwork?.mastodon,
75
+ telegram: (val, full) => full?.socialNetwork?.telegram,
76
+ signal: (val, full) => full?.socialNetwork?.signal
77
+ };
49
78
 
50
79
  /**
51
- * Crée une instance de User.
80
+ * Crée une instance de `User`.
52
81
  *
53
- * @param {ApiClient} apiClient - Le client API connecté.
54
- * @param {Object} data - Données initiales (peuvent inclure `id`, `slug`, etc.).
55
- * @param {string} [data.id] - ID de l'utilisateur.
56
- * @param {string} [data.slug] - Slug de l'utilisateur.
57
- * @param {Object} deps - Dépendances injectées.
58
- * @param {function|object} deps.EndpointApi - Classe ou instance de EndpointApi.
59
- * @param {function} deps.Organization - Classe Organization.
60
- * @param {function} deps.Project - Classe Project.
61
- * @param {function} deps.Event - Classe Events.
62
- * @param {function} deps.Poi - Classe Poi.
63
- * @param {function} deps.Badge - Classe Badge.
64
- * @param {function} deps.News - Classe News.
65
- *
66
- * @throws {ApiError} - Si des dépendances nécessaires sont manquantes ou invalides.
67
- */
68
-
69
- constructor(parent, data = {}, deps = {}) {
82
+ * @param parent
83
+ * L'ApiClient, une entité parente, ou tout objet exposant `apiClient`.
84
+ * @param {{ id?: string, slug?: string }} data Données initiales (il faut au moins `id` OU `slug`).
85
+ * @param {{
86
+ * EndpointApi: EndpointApiDep,
87
+ * Organization: typeof import("./Organization.js").Organization,
88
+ * Project: typeof import("./Project.js").Project,
89
+ * Event: typeof import("./Event.js").Event,
90
+ * Poi: typeof import("./Poi.js").Poi,
91
+ * Badge: typeof import("./Badge.js").Badge,
92
+ * News: typeof import("./News.js").News
93
+ * }} deps
94
+ * @throws {ApiError} Si `EndpointApi` n'est pas injecté, ou si `id`/`slug` manquent,
95
+ * ou si une des classes dépendantes n'est pas injectée.
96
+ */
97
+ constructor(
98
+ parent: ApiClient | any,
99
+ data: { id?: string; slug?: string },
100
+ deps: {
101
+ EndpointApi: any;
102
+ Organization: typeof import("./Organization.js").Organization;
103
+ Project: typeof import("./Project.js").Project;
104
+ Event: typeof import("./Event.js").Event;
105
+ Poi: typeof import("./Poi.js").Poi;
106
+ Badge: typeof import("./Badge.js").Badge;
107
+ News: typeof import("./News.js").News;
108
+ Comment: typeof import("./Comment.js").Comment;
109
+ }
110
+ ) {
70
111
  if(!deps.EndpointApi){
71
- throw new ApiError("EndpointApi class must be injected to avoid circular dependency.");
112
+ throw new ApiError("EndpointApi class must be injected to avoid circular dependency.", 500);
72
113
  }
73
114
  if (!data?.id && !data?.slug) {
74
- throw new ApiError("Vous devez fournir un id ou un slug pour créer un User.");
115
+ throw new ApiError("Vous devez fournir un id ou un slug pour créer un User.", 400);
75
116
  }
76
117
 
77
- if (!deps.Organization) throw new ApiError("Organization class must be injected.");
78
- if (!deps.Project) throw new ApiError("Project class must be injected.");
79
- if (!deps.Event) throw new ApiError("Event class must be injected.");
80
- if (!deps.Poi) throw new ApiError("Poi class must be injected.");
81
- if (!deps.Badge) throw new ApiError("Badge class must be injected.");
82
- if (!deps.News) throw new ApiError("News class must be injected.");
83
-
118
+ if (!deps.Organization) throw new ApiError("Organization class must be injected.", 500);
119
+ if (!deps.Project) throw new ApiError("Project class must be injected.", 500);
120
+ if (!deps.Event) throw new ApiError("Event class must be injected.", 500);
121
+ if (!deps.Poi) throw new ApiError("Poi class must be injected.", 500);
122
+ if (!deps.Badge) throw new ApiError("Badge class must be injected.", 500);
123
+ if (!deps.News) throw new ApiError("News class must be injected.", 500);
124
+
84
125
  super(parent, data, deps);
85
126
  }
86
127
 
87
- get slug() {
128
+ override get slug() {
88
129
  return this._draftData.slug || null;
89
130
  }
90
-
91
- get isMe() {
131
+
132
+ override get isMe() {
92
133
  return this.isConnected && this.userId === this.id;
93
134
  }
94
135
 
@@ -100,22 +141,25 @@ export class User extends BaseEntity {
100
141
  return this.parentIsMe && !this.isMe;
101
142
  }
102
143
 
144
+ /** @returns {"citoyens"} */
145
+ override getEntityType(): "citoyens" { return "citoyens"; }
146
+
103
147
  /**
104
148
  * Récupère le profil complet de l'utilisateur.
105
149
  * Si l'utilisateur est connecté, on appelle le endpoint ME_INFO_URL,
106
150
  * sinon, on peut imaginer appeler un endpoint public.
107
151
  *
108
- * @returns {Promise<Object>} Le profil complet.
152
+ * @returns Le profil complet.
109
153
  */
110
- async get() {
154
+ override async get(): Promise<Record<string, any>> {
111
155
  return this.apiClient.safeCall(async () => {
112
156
  if (this.isMe) {
113
157
  const data = await this.endpointApi.meInfoUrl();
114
- this._setData(data);
158
+ this._setData(data as UserItemNormalized, { forceInitialDraftReset: true });
115
159
  return data;
116
160
  } else {
117
161
  const data = await this._getPublicProfile();
118
- this._setData(data);
162
+ this._setData(data as UserItemNormalized, { forceInitialDraftReset: true });
119
163
  return data;
120
164
  }
121
165
  });
@@ -124,16 +168,26 @@ export class User extends BaseEntity {
124
168
  /**
125
169
  * Changer le mot de passe : Permet de changer le mot de passe d'un utilisateur.
126
170
  * Constant : CHANGE_PASSWORD
171
+ * @param data - Données envoyées à l'API
172
+ * @returns - Les données de réponse.
173
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
174
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
175
+ * @throws {Error} - En cas d'erreur inattendue.
127
176
  */
128
- async changePassword(data = {}) {
177
+ async changePassword(data: ChangePasswordData): Promise<unknown> {
129
178
  return this.callIsMe(() => this.endpointApi.changePassword(data));
130
179
  }
131
180
 
132
181
  /**
133
182
  * Supprimer un compte : Permet de supprimer un compte utilisateur.
134
183
  * Constant : DELETE_ACCOUNT
184
+ * @param data - Données envoyées à l'API
185
+ * @returns - Les données de réponse.
186
+ * @throws {ApiResponseError} - En cas d'erreur détectée dans la réponse.
187
+ * @throws {ApiAuthenticationError} - En cas d'erreur d'authentification.
188
+ * @throws {Error} - En cas d'erreur inattendue.
135
189
  */
136
- async delete(data = {}) {
190
+ async delete(data: DeleteAccountData): Promise<unknown> {
137
191
  return this.callIsMe(() => this.endpointApi.deleteAccount(data));
138
192
  }
139
193
 
@@ -141,39 +195,40 @@ export class User extends BaseEntity {
141
195
  * Sauvegarde les modifications de l'utilisateur en appelant les endpoints correspondants.
142
196
  * Seul l'utilisateur connecté peut se modifier lui-même.
143
197
  *
144
- * @returns {Promise<Object>} - Données serveur mises à jour si applicable.
198
+ * @returns - Données serveur mises à jour si applicable.
145
199
  * @throws {ApiError} - Si l'utilisateur n'est pas autorisé.
146
200
  */
147
- async save() {
201
+ override async save(): Promise<Record<string, any>> {
148
202
  if(!this.isMe){
149
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour sauvegarder.");
203
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour sauvegarder.", 401);
150
204
  }
151
- await super.save();
205
+ return await super.save();
152
206
  }
153
207
 
154
- async _add() {
155
- throw new ApiError("Vous ne pouvez pas ajouter un utilisateur par ce moyen.");
156
- }
208
+ override _add = async () => {
209
+ throw new ApiError("Vous ne pouvez pas ajouter un utilisateur par ce moyen.", 403);
210
+ };
157
211
 
158
212
  /**
159
213
  * Met à jour les blocs modifiés de l'utilisateur via les constantes de schéma définies.
160
214
  *
161
- * @param {Object} payload - Données courantes à comparer et envoyer.
162
- * @returns {Promise<boolean>} - Indique s'il y a eu une modification réelle.
215
+ * @param payload - Données courantes à comparer et envoyer.
216
+ * @returns - Indique s'il y a eu une modification réelle.
217
+ * @throws {ApiError} - Si l'utilisateur n'est pas autorisé à effectuer cette action.
163
218
  */
164
- async _update(payload){
219
+ override _update = async (payload: Record<string, any>): Promise<boolean> => {
165
220
  if (!this._calledFromSave) {
166
- throw new Error("utilisation invalide de _update, utilisez save");
221
+ throw new ApiError("utilisation invalide de _update, utilisez save", 400);
167
222
  }
168
223
 
169
- if(payload.id){
224
+ if (payload.id) {
170
225
  delete payload.id;
171
226
  }
172
227
 
173
228
  let hasChanged = false;
174
229
 
175
230
  // Sinon, on fait les updates en blocs
176
- for (const [constant, methodName] of User.UPDATE_BLOCKS) {
231
+ for (const [constant, methodName] of Array.from(User.UPDATE_BLOCKS)) {
177
232
  const blockData = this._extractChangedFieldsFromSchema(
178
233
  this.apiClient,
179
234
  constant,
@@ -182,110 +237,118 @@ export class User extends BaseEntity {
182
237
  this.removeFields
183
238
  );
184
239
  if (blockData && Object.keys(blockData).length > 0) {
185
- await this[methodName](blockData);
240
+ await this._invokeBlockMethod(User.UPDATE_BLOCKS, methodName, blockData);
186
241
  hasChanged = true;
187
242
  }
188
243
  }
189
244
 
190
245
  return hasChanged;
191
- }
246
+ };
192
247
 
193
- static fromServerData(data, parent, deps) {
194
- const instance = new User(parent.apiClient, data, deps);
195
- if (typeof data === "object" || Object.keys(data).length > 0) {
196
- instance._setData(data);
248
+ static override fromServerData(data: any, parent: any, deps: any): User {
249
+ const Ctor = this as any;
250
+ const instance = new Ctor(parent, data, deps);
251
+ if (data && typeof data === "object" && Object.keys(data).length > 0 && typeof instance._setData === "function") {
252
+ instance._setData(data as UserItemNormalized);
197
253
  }
198
254
  return instance;
199
255
  }
200
256
 
201
257
  /**
258
+ * {@inheritDoc BaseEntity#updateSettings}
259
+ *
202
260
  * Mettre à jour les paramètres utilisateur : Mise à jour des paramètres spécifiques d'un utilisateur.
203
- * Constant : UPDATE_SETTINGS
204
- * @param {Object} data - Données à mettre à jour.
205
- * @param {"birthDate"|"email"|"locality"|"phone"|"directory"} data.type - Type de paramètre à mettre à jour.
206
- * @param {"private"|"public"|"mask"} data.value - Nouvelle valeur du paramètre.
207
- * @returns {Promise<void>} - Résultat de la mise à jour.
208
261
  */
209
- async updateSettings(data = {}) {
262
+ override async updateSettings(data: Parameters<BaseEntity<UserItemNormalized>["updateSettings"]>[0]) {
210
263
  if(!this.isMe){
211
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour les paramètres.");
264
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour les paramètres.", 401);
212
265
  }
213
- await super.updateSettings(data);
266
+ const result = await super.updateSettings(data);
214
267
  await this.refresh();
268
+ return result;
215
269
  }
216
270
 
217
271
  /**
272
+ * {@inheritDoc BaseEntity#updateDescription}
273
+ *
218
274
  * Mettre à jour la description d'un élément : Permet de mettre à jour la description courte et complète d'un élément.
219
- * Constant : UPDATE_BLOCK_DESCRIPTION
220
275
  */
221
- async updateDescription(data = {}) {
276
+ override async updateDescription(data: Parameters<BaseEntity<UserItemNormalized>["updateDescription"]>[0]) {
222
277
  if(!this.isMe){
223
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour la description.");
278
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour la description.", 401);
224
279
  }
225
280
  return super.updateDescription(data);
226
281
  }
227
-
282
+
228
283
  /**
229
- * Mettre à jour les informations d'un élément : Permet de mettre à jour les informations générales d'un élément (nom, contacts, etc.).
230
- * Constant : UPDATE_BLOCK_INFO
231
- */
232
- async updateInfo(data = {}) {
284
+ * {@inheritDoc BaseEntity#updateInfo}
285
+ *
286
+ * Mettre à jour les informations d'un élément : Permet de mettre à jour les informations générales d'un élément (nom, contacts, etc.).
287
+ */
288
+ override async updateInfo(data: Parameters<BaseEntity<UserItemNormalized>["updateInfo"]>[0]) {
233
289
  if(!this.isMe){
234
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour les informations.");
290
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour les informations.", 401);
235
291
  }
236
292
  return super.updateInfo(data);
237
293
  }
238
-
294
+
239
295
  /**
240
- * Mettre à jour les réseaux sociaux d'un élément : Permet de mettre à jour les liens vers les réseaux sociaux d'un élément.
241
- * Constant : UPDATE_BLOCK_SOCIAL
242
- */
243
- async updateSocial(data = {}) {
296
+ * {@inheritDoc BaseEntity#updateSocial}
297
+ *
298
+ * Mettre à jour les réseaux sociaux d'un élément : Permet de mettre à jour les liens vers les réseaux sociaux d'un élément.
299
+ */
300
+ override async updateSocial(data: Parameters<BaseEntity<UserItemNormalized>["updateSocial"]>[0]) {
244
301
  if(!this.isMe){
245
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour les réseaux sociaux.");
302
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour les réseaux sociaux.", 401);
246
303
  }
247
304
  return super.updateSocial(data);
248
305
  }
249
-
306
+
250
307
  /**
251
- * Mettre à jour les localités d'un élément : Permet de mettre à jour l'adresse et les informations géographiques d'un élément.
252
- * Constant : UPDATE_BLOCK_LOCALITY
253
- */
254
- async updateLocality(data = {}) {
308
+ * {@inheritDoc BaseEntity#updateLocality}
309
+ *
310
+ * Mettre à jour les localités d'un élément : Permet de mettre à jour l'adresse et les informations géographiques d'un élément.
311
+ */
312
+ override async updateLocality(data: Parameters<BaseEntity<UserItemNormalized>["updateLocality"]>[0]) {
255
313
  if(!this.isMe){
256
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour la localité.");
314
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour la localité.", 401);
257
315
  }
258
316
  return super.updateLocality(data);
259
317
  }
260
-
318
+
261
319
  /**
262
- * Mettre à jour le slug d'un élément : Permet de mettre à jour le slug pour une URL simplifiée.
263
- * Constant : UPDATE_BLOCK_SLUG
264
- */
265
- async updateSlug({ slug }) {
320
+ * {@inheritDoc BaseEntity#updateSlug}
321
+ *
322
+ * Mettre à jour le slug d'un élément : Permet de mettre à jour le slug pour une URL simplifiée.
323
+ */
324
+ override async updateSlug(data: Parameters<BaseEntity<UserItemNormalized>["updateSlug"]>[0]) {
266
325
  if(!this.isMe){
267
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour le slug.");
326
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour le slug.", 401);
268
327
  }
269
- return super.updateSlug({ slug });
328
+ return super.updateSlug(data);
270
329
  }
271
330
 
272
331
  /**
332
+ * {@inheritDoc BaseEntity#updateImageProfil}
333
+ *
273
334
  * Mettre à jour l'image de profil : Permet de mettre à jour l'image de profil d'un utilisateur ou d'une entité.
274
- * Constant : PROFIL_IMAGE
275
335
  */
276
- async updateImageProfil({ profil_avatar: image }) {
336
+ override async updateImageProfil(data: Parameters<BaseEntity<UserItemNormalized>["updateImageProfil"]>[0]) {
277
337
  if(!this.isMe){
278
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour l'image de profil.");
338
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour mettre à jour l'image de profil.", 401);
279
339
  }
280
- return super.updateImageProfil({ profil_avatar: image });
340
+ return super.updateImageProfil(data);
281
341
  }
282
342
 
283
343
  /**
344
+ * {@inheritDoc BaseEntity#getOrganizations}
345
+ * @param [data]
346
+ *
284
347
  * Récupérer les organisations d'un utilisateur : Récupère la liste des organisations auxquelles l'utilisateur appartient.
285
348
  * Constant : GET_ORGANIZATIONS_ADMIN | GET_ORGANIZATIONS_NO_ADMIN
286
349
  */
287
- async getOrganizations(data = {}) {
288
- data.searchType = this._getDefaultFromEndpoint("GET_ORGANIZATIONS_NO_ADMIN", "searchType");
350
+ override async getOrganizations(data: Partial<GetOrganizationsAdminData | GetOrganizationsNoAdminData> = {}) {
351
+ data.searchType = this._getDefaultFromEndpoint("GET_ORGANIZATIONS_NO_ADMIN", "searchType") as GetOrganizationsNoAdminData["searchType"];
289
352
  // data.searchBy = "ALL";
290
353
 
291
354
  const paginator = this._createPaginatorEngine({
@@ -296,7 +359,7 @@ export class User extends BaseEntity {
296
359
  const fetchFn = this.isMe
297
360
  ? () => this.callIsMe(() => this.endpointApi.getOrganizationsAdmin(finalData))
298
361
  : () => this.endpointApi.getOrganizationsNoAdmin(finalData);
299
-
362
+
300
363
  if (!this.isMe && !finalData.filters) {
301
364
  finalData.filters = {
302
365
  [`links.members.${this.id}`]: { "$exists": true },
@@ -309,30 +372,33 @@ export class User extends BaseEntity {
309
372
  }
310
373
  });
311
374
 
312
- return paginator.next();
375
+ return paginator.next() as Promise<PaginatorPage<Organization>>;
313
376
  }
314
377
 
315
378
  /**
379
+ * {@inheritDoc BaseEntity#getProjects}
380
+ *
316
381
  * Récupérer les projets d'un utilisateur : Récupère la liste des projets auxquels l'utilisateur contribue.
317
- * Constant : GET_PROJECTS_ADMIN | GET_PROJECTS_NO_ADMIN
318
382
  */
319
- async getProjects(data = {}) {
383
+ override async getProjects(data: Parameters<BaseEntity<UserItemNormalized>["getProjects"]>[0] = {}) {
320
384
  return super.getProjects(data);
321
385
  }
322
386
 
323
387
  /**
388
+ * {@inheritDoc BaseEntity#getPois}
389
+ *
324
390
  * Récupérer les POIs
325
- * Constant : GET_POIS_NO_ADMIN / GET_POIS_ADMIN
326
391
  */
327
- async getPois(data = {}) {
392
+ override async getPois(data: Parameters<BaseEntity<UserItemNormalized>["getPois"]>[0] = {}) {
328
393
  return super.getPois(data);
329
394
  }
330
395
 
331
396
  /**
397
+ * {@inheritDoc BaseEntity#getNews}
398
+ *
332
399
  * Récupérer les actualités : Récupère la liste des actualités liées à l'utilisateur.
333
- * Constant : GET_NEWS
334
400
  */
335
- async getNews(data = {}) {
401
+ override async getNews(data: Parameters<BaseEntity<UserItemNormalized>["getNews"]>[0] = {}) {
336
402
  return super.getNews(data);
337
403
  }
338
404
 
@@ -342,8 +408,8 @@ export class User extends BaseEntity {
342
408
  * question : qui peut voir la liste d'amis, seulement l'utilisateur connecté ? ou tous les utilisateurs connectés ?
343
409
  * actuellement, c'est tous les utilisateurs connectés
344
410
  */
345
- async getFriends(data = {}) {
346
- data.searchType = this._getDefaultFromEndpoint("GET_FRIENDS_ADMIN", "searchType");
411
+ async getFriends(data: Partial<GetFriendsAdminData> = {}): Promise<PaginatorPage<User>> {
412
+ data.searchType = this._getDefaultFromEndpoint("GET_FRIENDS_ADMIN", "searchType") as GetFriendsAdminData["searchType"];
347
413
  // data.searchBy = "ALL";
348
414
 
349
415
  const paginator = this._createPaginatorEngine({
@@ -351,25 +417,25 @@ export class User extends BaseEntity {
351
417
  finalizer: async (finalData) => {
352
418
 
353
419
  delete finalData?.pathParams;
354
-
355
- if (!this.isMe){
420
+
421
+ if (!this.isMe && this.id){
356
422
  // is not me add id
357
423
  finalData.pathParams = { id: this.id };
358
424
  }
359
425
 
360
- return this.endpointApi.getFriendsAdmin(finalData);;
426
+ return this.endpointApi.getFriendsAdmin(finalData);
361
427
  }
362
428
  });
363
429
 
364
- return paginator.next();
430
+ return paginator.next() as Promise<PaginatorPage<User>>;
365
431
  }
366
432
 
367
433
  /**
368
434
  * Récupérer les suivis
369
435
  * Constant : GET_SUBSCRIPTIONS / GET_SUBSCRIPTIONS_ADMIN
370
436
  */
371
- async getSubscriptions(data = {}) {
372
- data.searchType = this._getDefaultFromEndpoint("GET_SUBSCRIPTIONS", "searchType");
437
+ async getSubscriptions(data: Partial<GetSubscriptionsAdminData | GetSubscriptionsData> = {}): Promise<PaginatorPage<BaseEntity<any>>> {
438
+ data.searchType = this._getDefaultFromEndpoint("GET_SUBSCRIPTIONS", "searchType") as GetSubscriptionsAdminData["searchType"];
373
439
  // data.searchBy = "ALL";
374
440
 
375
441
  const paginator = this._createPaginatorEngine({
@@ -377,11 +443,11 @@ export class User extends BaseEntity {
377
443
  finalizer: async (finalData) => {
378
444
 
379
445
  delete finalData?.pathParams;
380
-
446
+
381
447
  const fetchFn = this.isMe
382
448
  ? () => this.callIsMe(() => this.endpointApi.getSubscriptionsAdmin(finalData))
383
449
  : () => this.endpointApi.getSubscriptions(finalData);
384
-
450
+
385
451
  if (!this.isMe && !finalData.filters) {
386
452
  finalData.filters = {
387
453
  [`links.followers.${this.id}`]: { "$exists": true },
@@ -392,14 +458,15 @@ export class User extends BaseEntity {
392
458
  }
393
459
  });
394
460
 
395
- return paginator.next();
461
+ return paginator.next() as Promise<PaginatorPage<BaseEntity<any>>>;
396
462
  }
397
463
 
398
464
  /**
465
+ * {@inheritDoc BaseEntity#getSubscribers}
466
+ *
399
467
  * Récupérer les abonnés
400
- * Constant : GET_SUBSCRIBERS
401
468
  */
402
- async getSubscribers(data = {}) {
469
+ override async getSubscribers(data: Parameters<BaseEntity<UserItemNormalized>["getSubscribers"]>[0] = {}) {
403
470
  return super.getSubscribers(data);
404
471
  }
405
472
 
@@ -410,10 +477,11 @@ export class User extends BaseEntity {
410
477
  */
411
478
 
412
479
  /**
480
+ * {@inheritDoc BaseEntity#getBadgesIssuer}
481
+ *
413
482
  * Liste des badges créés par l'utilisateur
414
- * Constant : GET_BADGES
415
483
  */
416
- async getBadgesIssuer(data = {}) {
484
+ override async getBadgesIssuer(data: Parameters<BaseEntity<UserItemNormalized>["getBadgesIssuer"]>[0] = {}) {
417
485
  return super.getBadgesIssuer(data);
418
486
  }
419
487
 
@@ -422,7 +490,7 @@ export class User extends BaseEntity {
422
490
  *
423
491
  * TODO : documenté le fonctionnement et sont utilisation avec un exemple
424
492
  */
425
- async getBadges(filter = {}) {
493
+ async getBadges(filter: Record<string, any> = {}): Promise<Badge[]> {
426
494
  /*
427
495
  "badges": {
428
496
  "627df5663a0fae60e57f4a31": {
@@ -442,105 +510,95 @@ export class User extends BaseEntity {
442
510
  }
443
511
 
444
512
  /**
513
+ * {@inheritDoc BaseEntity#getGallery}
514
+ *
445
515
  * Récupérer la galerie de l'utilisateur
446
- * Constant : GET_GALLERY
447
516
  */
448
- async getGallery(data = {}) {
517
+ override async getGallery(data: Parameters<BaseEntity<UserItemNormalized>["getGallery"]>[0] = {}) {
449
518
  return super.getGallery(data);
450
519
  }
451
520
 
452
- async user(userData) {
521
+ async user(userData: { id?: string, slug?: string }): Promise<User> {
453
522
  if(!this.isMe){
454
- throw new ApiError("Vous devez être connecté et être l'utilisateur");
523
+ throw new ApiError("Vous devez être connecté et être l'utilisateur", 401);
455
524
  }
456
525
  if (!userData.id && !userData.slug) {
457
- throw new ApiError("Vous devez fournir un id ou un slug pour créer un User.");
526
+ throw new ApiError("Vous devez fournir un id ou un slug pour créer un User.", 400);
458
527
  }
459
- const user = new User(this, userData, this.deps);
528
+ const requiredDeps = this.deps as any;
529
+ const user = new User(this, userData, requiredDeps as any);
460
530
  await user.get();
461
531
  return user;
462
532
  }
463
533
 
464
534
  /**
535
+ * {@inheritDoc BaseEntity#organization}
536
+ *
465
537
  * Crée une instance d'organisation et récupère son profil si nécessaire.
466
- *
467
- * @param {Object} organizationData - Les données nécessaires pour initialiser l'organisation.
468
- * @returns {Promise<Organization>} Une promesse qui résout l'objet Organisation créé.
469
- * @throws {Error} Si une erreur se produit lors de la création de l'organisation.
470
538
  */
471
- async organization(organizationData = {}) {
539
+ override async organization(organizationData: Parameters<BaseEntity<UserItemNormalized>["organization"]>[0] = {}) {
472
540
  if(!this.isMe){
473
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer une organisation.");
541
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer une organisation.", 401);
474
542
  }
475
543
  return super.organization(organizationData);
476
544
  }
477
545
 
478
546
  /**
547
+ * {@inheritDoc BaseEntity#project}
548
+ *
479
549
  * Crée une instance de projet et récupère son profil si nécessaire.
480
- *
481
- * @param {Object} projectData - Les données nécessaires pour initialiser le projet.
482
- * @returns {Promise<Project>} Une promesse qui résout l'objet Projet créé.
483
- * @throws {Error} Si une erreur se produit lors de la création du projet.
484
550
  */
485
- async project(projectData = {}) {
551
+ override async project(projectData: Parameters<BaseEntity<UserItemNormalized>["project"]>[0] = {}) {
486
552
  if(!this.isMe){
487
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer un projet.");
553
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer un projet.", 401);
488
554
  }
489
555
  return super.project(projectData);
490
556
  }
491
557
 
492
558
  /**
493
- * Crée une instance de news et la récupère si nécessaire.
559
+ * {@inheritDoc BaseEntity#news}
494
560
  *
495
- * @param {Object} newsData - Les données nécessaires pour initialiser la news.
496
- * @returns {Promise<News>} Une promesse qui résout l'objet News créé.
497
- * @throws {Error} Si une erreur se produit lors de la création de la news.
561
+ * Crée une instance de news et la récupère si nécessaire.
498
562
  */
499
- async news(newsData = {}) {
563
+ override async news(newsData: Parameters<BaseEntity<UserItemNormalized>["news"]>[0] = {}) {
500
564
  if(!this.isMe){
501
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer une actualité.");
565
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer une actualité.", 401);
502
566
  }
503
567
  return super.news(newsData);
504
568
  }
505
569
 
506
570
  /**
507
- * Crée une instance de POI et la récupère si nécessaire.
571
+ * {@inheritDoc BaseEntity#poi}
508
572
  *
509
- * @param {Object} poiData - Les données nécessaires pour initialiser le POI.
510
- * @returns {Promise<Poi>} Une promesse qui résout l'objet POI créé.
511
- * @throws {Error} Si une erreur se produit lors de la création du POI.
573
+ * Crée une instance de POI et la récupère si nécessaire.
512
574
  */
513
- async poi(poiData = {}) {
575
+ override async poi(poiData: Parameters<BaseEntity<UserItemNormalized>["poi"]>[0] = {}) {
514
576
  if(!this.isMe){
515
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer un POI.");
577
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer un POI.", 401);
516
578
  }
517
579
  return super.poi(poiData);
518
580
  }
519
581
 
520
582
  /**
521
- * Crée une instance d'événement et la récupère si nécessaire.
583
+ * {@inheritDoc BaseEntity#event}
522
584
  *
523
- * @param {Object} eventData - Les données nécessaires pour initialiser l'événement.
524
- * @returns {Promise<Event>} Une promesse qui résout l'objet Événement créé.
525
- * @throws {Error} Si une erreur se produit lors de la création de l'événement.
585
+ * Crée une instance d'événement et la récupère si nécessaire.
526
586
  */
527
- async event(eventData = {}) {
587
+ override async event(eventData: Parameters<BaseEntity<UserItemNormalized>["event"]>[0] = {}) {
528
588
  if(!this.isMe){
529
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer un événement.");
589
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer un événement.", 401);
530
590
  }
531
591
  return super.event(eventData);
532
592
  }
533
593
 
534
594
  /**
535
- * Crée une instance de badge et la récupère si nécessaire.
595
+ * {@inheritDoc BaseEntity#badge}
536
596
  *
537
- * @param {Object} badgeData - Les données nécessaires pour initialiser le badge.
538
- * @returns {Promise<Badge>} Une promesse qui résout l'objet Badge créé.
539
- * @throws {Error} Si une erreur se produit lors de la création du badge.
597
+ * Crée une instance de badge et la récupère si nécessaire.
540
598
  */
541
- async badge(badgeData = {}) {
599
+ override async badge(badgeData: Parameters<BaseEntity<UserItemNormalized>["badge"]>[0] = {}) {
542
600
  if(!this.isMe){
543
- throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer un badge.");
601
+ throw new ApiError("Vous devez être connecté et être l'utilisateur pour créer un badge.", 401);
544
602
  }
545
603
  return super.badge(badgeData);
546
604
  }
@@ -556,31 +614,33 @@ export class User extends BaseEntity {
556
614
  * Envoie une demande d'amitié à cet utilisateur.
557
615
  * L'utilisateur ciblé devra valider la demande pour établir la relation.
558
616
  *
559
- * @returns {Promise<Object>} - Résultat de la requête.
617
+ * @returns - Résultat de la requête.
560
618
  * @throws {ApiError} - Si l'utilisateur n'est pas connecté ou si l'action est interdite.
561
619
  */
562
- async sendFriendRequest() {
563
- if (!this.isActingUser) {
564
- throw new ApiError("Vous devez être connecté pour envoyer une demande d'amis.");
620
+ async sendFriendRequest(): Promise<unknown> {
621
+ if (!this.isActingUser || !this.userId) {
622
+ throw new ApiError("Vous devez être connecté pour envoyer une demande d'amis.", 401);
565
623
  }
566
624
 
567
625
  this._checkLinkableEntity();
568
626
  if (!this.id) {
569
- throw new ApiError(`${this.constructor.name} non enregistrée.`);
627
+ throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
570
628
  }
571
629
 
572
630
  const { connectTypeConnect } = this._getLinkMeta();
573
631
  const userLink = this._getLinkFromConnectedUser();
574
632
 
575
633
  if (!userLink) {
576
- const data = {
634
+ const data: ConnectData = {
635
+ childId: this.userId,
636
+ childType: "citoyens",
577
637
  parentType: this.getEntityType(),
578
638
  parentId: this.id,
579
639
  connectType: connectTypeConnect
580
640
  };
581
641
  const retour = await this.endpointApi.connect(data);
582
642
  // TODO : reflechier au moyen de remplir parent.serverData et this.serverData avec les data de retour pour eviter un refresh
583
- await this.userContext.refresh();
643
+ await this.userContext?.refresh();
584
644
  return retour;
585
645
  }
586
646
 
@@ -589,172 +649,179 @@ export class User extends BaseEntity {
589
649
  }
590
650
 
591
651
  if (userLink.isInviting && userLink.invitorId === this.userId) {
592
- throw new ApiError("Vous avez déjà envoyé une demande d'amis à cet utilisateur.");
652
+ throw new ApiError("Vous avez déjà envoyé une demande d'amis à cet utilisateur.", 403);
593
653
  }
594
654
 
595
- throw new ApiError("Vous êtes déjà connecté à cette entité.");
655
+ throw new ApiError("Vous êtes déjà connecté à cette entité.", 409);
596
656
  }
597
657
 
598
658
  /**
599
659
  * Accepte une demande d'amitié envoyée par cet utilisateur.
600
660
  * Cette action établit un lien entre les deux utilisateurs.
601
661
  *
602
- * @returns {Promise<Object>} - Résultat de la validation du lien.
662
+ * @returns - Résultat de la validation du lien.
603
663
  * @throws {ApiError} - Si aucune invitation n'est en attente ou si l'action est interdite.
604
664
  */
605
- async acceptFriendRequest() {
606
- if (!this.isActingUser) {
607
- throw new ApiError("Vous devez être connecté pour accepter une demande d'amitié.");
665
+ async acceptFriendRequest(): Promise<unknown> {
666
+ if (!this.isActingUser || !this.userId) {
667
+ throw new ApiError("Vous devez être connecté pour accepter une demande d'amitié.", 401);
608
668
  }
609
669
 
610
670
  this._checkLinkableEntity();
611
671
  if (!this.id) {
612
- throw new ApiError(`${this.constructor.name} non enregistrée.`);
672
+ throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
613
673
  }
614
674
 
615
675
  const userLink = this._getLinkFromConnectedUser();
616
676
 
617
677
  if (userLink?.isInviting && userLink.invitorId === this.id) {
618
- const data = {
678
+ const data: LinkValidateData = {
679
+ childId: this.userId,
680
+ childType: "citoyens",
619
681
  parentType: this.getEntityType(),
620
682
  parentId: this.id,
621
683
  linkOption: "isInviting"
622
684
  };
623
685
  const retour = await this.endpointApi.linkValidate(data);
624
686
  // TODO : reflechier au moyen de remplir parent.serverData et this.serverData avec les data de retour pour eviter un refresh
625
- await this.userContext.refresh();
687
+ await this.userContext?.refresh();
626
688
  return retour;
627
689
  }
628
690
 
629
- throw new ApiError("Vous n'avez pas d'invitation à valider.");
691
+ throw new ApiError("Vous n'avez pas d'invitation à valider.", 404);
630
692
  }
631
693
 
632
694
  /**
633
695
  * Supprime la relation d'amitié avec cet utilisateur.
634
696
  * Cette action annule tout lien existant entre les deux profils.
635
697
  *
636
- * @returns {Promise<Object>} - Résultat de la suppression.
698
+ * @returns - Résultat de la suppression.
637
699
  * @throws {ApiError} - Si aucune relation n'existe.
638
700
  */
639
- async removeFriend() {
640
- if (!this.isActingUser) {
641
- throw new ApiError("Vous devez être connecté pour supprimer un ami.");
701
+ async removeFriend(): Promise<unknown> {
702
+ if (!this.isActingUser || !this.userId) {
703
+ throw new ApiError("Vous devez être connecté pour supprimer un ami.", 401);
642
704
  }
643
705
 
644
706
  this._checkLinkableEntity();
645
707
  if (!this.id) {
646
- throw new ApiError(`${this.constructor.name} non enregistrée.`);
708
+ throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
647
709
  }
648
710
 
649
711
  const { connectTypeDisconnect } = this._getLinkMeta();
650
712
  const userLink = this._getLinkFromConnectedUser();
651
713
 
652
714
  if (!userLink) {
653
- throw new ApiError("Vous n'êtes pas connecté à cette entité.");
715
+ throw new ApiError("Vous n'êtes pas connecté à cette entité.", 404);
654
716
  }
655
-
656
- const data = {
717
+ const data: DisconnectData = {
718
+ childId: this.userId,
719
+ childType: "citoyens",
657
720
  parentType: this.getEntityType(),
658
721
  parentId: this.id,
659
722
  connectType: connectTypeDisconnect
660
723
  };
661
724
  const retour = await this.endpointApi.disconnect(data);
662
725
  // TODO : reflechier au moyen de remplir parent.serverData et this.serverData avec les data de retour pour eviter un refresh
663
- await this.userContext.refresh();
726
+ await this.userContext?.refresh();
664
727
  return retour;
665
728
  }
666
729
 
667
730
 
668
- requestToJoin() {
669
- throw new ApiError("l'utilisation de requestToJoin n'est pas autorisée sur un utilisateur.");
731
+ override async requestToJoin(): Promise<never> {
732
+ throw new ApiError("l'utilisation de requestToJoin n'est pas autorisée sur un utilisateur.", 403);
670
733
  }
671
734
 
672
- requestToJoinAdmin() {
673
- throw new ApiError("l'utilisation de requestToJoinAdmin n'est pas autorisée sur un utilisateur.");
735
+ override async requestToJoinAdmin(): Promise<never> {
736
+ throw new ApiError("l'utilisation de requestToJoinAdmin n'est pas autorisée sur un utilisateur.", 403);
674
737
  }
675
738
 
676
- acceptInvitation() {
677
- throw new ApiError("l'utilisation de acceptInvitation n'est pas autorisée sur un utilisateur.");
739
+ override async acceptInvitation(): Promise<never> {
740
+ throw new ApiError("l'utilisation de acceptInvitation n'est pas autorisée sur un utilisateur.", 403);
678
741
  }
679
742
 
680
- leave() {
681
- throw new ApiError("l'utilisation de leave n'est pas autorisée sur un utilisateur.");
743
+ override async leave(): Promise<never> {
744
+ throw new ApiError("l'utilisation de leave n'est pas autorisée sur un utilisateur.", 403);
682
745
  }
683
746
 
684
747
  /**
685
748
  * Suivre un utilisateur
686
749
  * Cette action permet à l'utilisateur connecté de suivre un autre utilisateur.
687
750
  * Elle nécessite que l'utilisateur soit connecté.
688
- *
689
- * @returns {Promise<Object>} - Résultat de la requête.
751
+ *
752
+ * @returns - Résultat de la requête.
690
753
  * @throws {ApiError} - Si l'utilisateur n'est pas connecté ou si l'action est interdite.
691
754
  */
692
- async follow() {
693
- if (!this.isActingUser) {
694
- throw new ApiError("Vous devez être connecté pour suivre un utilisateur.");
755
+ override async follow(): Promise<unknown> {
756
+ if (!this.isActingUser || !this.userId) {
757
+ throw new ApiError("Vous devez être connecté pour suivre un utilisateur.", 401);
695
758
  }
696
759
  if (!this.id) {
697
- throw new ApiError(`${this.constructor.name} non enregistrée.`);
760
+ throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
698
761
  }
699
762
 
700
763
  const userLink = this.userContext?.serverData?.links?.["follows"]?.[this.id] || null;
701
764
 
702
765
  if (!userLink) {
703
- const data = {
766
+ const data: FollowData = {
767
+ childId: this.userId,
768
+ childType: "citoyens",
704
769
  parentType: this.getEntityType(),
705
770
  parentId: this.id
706
771
  };
707
772
  const retour = await this.endpointApi.follow(data);
708
773
  // TODO : reflechier au moyen de remplir parent.serverData et this.serverData avec les data de retour pour eviter un refresh
709
- await this.userContext.refresh();
774
+ await this.userContext?.refresh();
710
775
  return retour;
711
776
  }
712
777
 
713
- throw new ApiError("Vous êtes déjà abonné à cet utilisateur.");
778
+ throw new ApiError("Vous êtes déjà abonné à cet utilisateur.", 409);
714
779
  }
715
780
 
716
781
  /**
717
782
  * Se désabonner d'un utilisateur
718
783
  * Cette action permet à l'utilisateur connecté de se désabonner d'un autre utilisateur.
719
784
  * Elle nécessite que l'utilisateur soit connecté.
720
- *
721
- * @returns {Promise<Object>} - Résultat de la requête.
785
+ *
786
+ * @returns - Résultat de la requête.
722
787
  * @throws {ApiError} - Si l'utilisateur n'est pas connecté ou si l'action est interdite.
723
788
  */
724
- async unfollow() {
725
- if (!this.isActingUser) {
726
- throw new ApiError("Vous devez être connecté pour vous désabonner d'un utilisateur.");
789
+ override async unfollow(): Promise<unknown> {
790
+ if (!this.isActingUser || !this.userId) {
791
+ throw new ApiError("Vous devez être connecté pour vous désabonner d'un utilisateur.", 401);
727
792
  }
728
793
  if (!this.id) {
729
- throw new ApiError(`${this.constructor.name} non enregistrée.`);
794
+ throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
730
795
  }
731
796
 
732
797
  const userLink = this.userContext?.serverData?.links?.["follows"]?.[this.id] || null;
733
798
 
734
799
  if (userLink) {
735
- const data = {
800
+ const data: DisconnectData = {
801
+ childId: this.userId,
802
+ childType: "citoyens",
736
803
  parentType: this.getEntityType(),
737
804
  parentId: this.id,
738
805
  connectType: "followers"
739
806
  };
740
807
  const retour = await this.endpointApi.disconnect(data);
741
808
  // TODO : reflechir au moyen de remplir parent.serverData et this.serverData avec les data de retour pour eviter un refresh
742
- await this.userContext.refresh();
809
+ await this.userContext?.refresh();
743
810
  return retour;
744
811
  }
745
812
 
746
- throw new ApiError("Vous n'êtes pas abonné à cet utilisateur.");
813
+ throw new ApiError("Vous n'êtes pas abonné à cet utilisateur.", 404);
747
814
  }
748
815
 
749
816
  /**
750
817
  * Vérifie si l'utilisateur connecté est ami avec cet utilisateur.
751
818
  *
752
- * @returns {boolean} - True si l'utilisateur connecté est ami, sinon false.
819
+ * @returns - True si l'utilisateur connecté est ami, sinon false.
753
820
  * @throws {ApiError} - Si l'utilisateur n'est pas connecté.
754
821
  */
755
- isFriend() {
822
+ isFriend(): boolean {
756
823
  if (!this.isActingUser) {
757
- throw new ApiError("Vous devez être connecté pour vérifier si vous êtes ami.");
824
+ throw new ApiError("Vous devez être connecté pour vérifier si vous êtes ami.", 401);
758
825
  }
759
826
  this._assertEntityType("citoyens");
760
827
  const userLink = this._getLinkFromConnectedUser();
@@ -763,16 +830,16 @@ export class User extends BaseEntity {
763
830
 
764
831
  /**
765
832
  * Vérifie si l'utilisateur suit l'entité.
766
- *
767
- * @returns {boolean} - `true` si l'utilisateur suit l'entité, `false` sinon.
833
+ *
834
+ * @returns - `true` si l'utilisateur suit l'entité, `false` sinon.
768
835
  * @throws {ApiError}
769
836
  */
770
- isFollower() {
837
+ override isFollower(): boolean {
771
838
  if (!this.isActingUser) {
772
- throw new ApiError("Vous devez être connecté pour vérifier si il vous suit.");
839
+ throw new ApiError("Vous devez être connecté pour vérifier si il vous suit.", 401);
773
840
  }
774
841
  if (!this.id) {
775
- throw new ApiError(`${this.constructor.name} non enregistrée.`);
842
+ throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
776
843
  }
777
844
  this._assertEntityType("citoyens");
778
845
  return this._isLinked("followers");
@@ -780,22 +847,20 @@ export class User extends BaseEntity {
780
847
 
781
848
  /**
782
849
  * Vérifie si l'utilisateur est abonné à l'entité.
783
- *
784
- * @returns {boolean} - `true` si l'utilisateur est abonné, `false` sinon.
850
+ *
851
+ * @returns - `true` si l'utilisateur est abonné, `false` sinon.
785
852
  * @throws {ApiError}
786
853
  */
787
- isFollowing() {
854
+ override isFollowing(): boolean {
788
855
  if (!this.isActingUser) {
789
- throw new ApiError("Vous devez être connecté pour vérifier si vous le suivez.");
856
+ throw new ApiError("Vous devez être connecté pour vérifier si vous le suivez.", 401);
790
857
  }
791
858
  if (!this.id) {
792
- throw new ApiError(`${this.constructor.name} non enregistrée.`);
859
+ throw new ApiError(`${this.constructor.name} non enregistrée.`, 404);
793
860
  }
794
861
  this._assertEntityType("citoyens");
795
862
  return this._isLinked("follows");
796
863
  }
797
-
798
-
799
864
  }
800
865
 
801
866
  // Incorporation des mixins dans User