@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.
- package/dist/401.cocolight-api-client.browser.js +1 -0
- package/dist/401.cocolight-api-client.cjs +1 -0
- package/dist/401.cocolight-api-client.mjs.js +1 -0
- package/dist/588.cocolight-api-client.browser.js +1 -0
- package/dist/588.cocolight-api-client.cjs +1 -0
- package/dist/588.cocolight-api-client.mjs.js +1 -0
- package/dist/593.cocolight-api-client.browser.js +1 -0
- package/dist/593.cocolight-api-client.cjs +1 -0
- package/dist/593.cocolight-api-client.mjs.js +1 -0
- package/dist/839.cocolight-api-client.browser.js +1 -0
- package/dist/839.cocolight-api-client.cjs +1 -0
- package/dist/839.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/dist/cocolight-api-client.vite.mjs.js +1 -1
- package/dist/cocolight-api-client.vite.mjs.js.map +1 -1
- package/package.json +29 -17
- package/src/{Api.js → Api.ts} +85 -95
- package/src/{ApiClient.js → ApiClient.ts} +436 -247
- package/src/EJSONType.ts +103 -0
- package/src/api/{Badge.js → Badge.ts} +56 -45
- package/src/api/BaseEntity.ts +3890 -0
- package/src/api/Comment.ts +200 -0
- package/src/api/{EndpointApi.js → EndpointApi.ts} +363 -297
- package/src/api/EndpointApi.types.ts +4609 -0
- package/src/api/EntityRegistry.ts +203 -0
- package/src/api/Event.ts +332 -0
- package/src/api/News.ts +331 -0
- package/src/api/{Organization.js → Organization.ts} +155 -119
- package/src/api/{Poi.js → Poi.ts} +68 -60
- package/src/api/{Project.js → Project.ts} +150 -127
- package/src/api/{User.js → User.ts} +321 -256
- package/src/api/UserApi.ts +148 -0
- package/src/api/serverDataType/Comment.ts +88 -0
- package/src/api/serverDataType/Event.ts +80 -0
- package/src/api/serverDataType/News.ts +138 -0
- package/src/api/serverDataType/Organization.ts +80 -0
- package/src/api/serverDataType/Project.ts +71 -0
- package/src/api/serverDataType/User.ts +103 -0
- package/src/api/serverDataType/common.ts +80 -0
- package/src/endpoints.module.ts +2621 -0
- package/src/error.ts +86 -0
- package/src/index.ts +86 -0
- package/src/mixin/UserMixin.ts +4 -0
- package/src/types/api-responses.ts +217 -0
- package/src/types/entities.ts +22 -0
- package/src/types/error-guards.ts +230 -0
- package/src/types/index.ts +39 -0
- package/src/types/payloads.ts +21 -0
- package/src/types/transforms.ts +110 -0
- package/src/utils/{FileOfflineStorageStrategy.node.js → FileOfflineStorageStrategy.node.ts} +15 -12
- package/src/utils/{FileStorageStrategy.node.js → FileStorageStrategy.node.ts} +16 -39
- package/src/utils/MultiServerFileStorageStrategy.node.ts +67 -0
- package/src/utils/MultiServerTokenStorageStrategy.ts +139 -0
- package/src/utils/{OfflineClientManager.js → OfflineClientManager.ts} +82 -86
- package/src/utils/OfflineQueueStorageStrategy.ts +47 -0
- package/src/utils/TokenStorage.ts +77 -0
- package/src/utils/compat.ts +12 -0
- package/src/utils/createDefaultMultiServerTokenStorageStrategy.ts +35 -0
- package/src/utils/{createDefaultOfflineStrategy.js → createDefaultOfflineStrategy.ts} +8 -3
- package/src/utils/createDefaultTokenStorageStrategy.ts +33 -0
- package/src/utils/{reactive.js → reactive.ts} +49 -40
- package/src/utils/stream-utils.node.ts +12 -0
- package/types/Api.d.ts +38 -82
- package/types/Api.d.ts.map +1 -0
- package/types/ApiClient.d.ts +244 -184
- package/types/ApiClient.d.ts.map +1 -0
- package/types/EJSONType.d.ts +48 -22
- package/types/EJSONType.d.ts.map +1 -0
- package/types/api/Badge.d.ts +20 -20
- package/types/api/Badge.d.ts.map +1 -0
- package/types/api/BaseEntity.d.ts +751 -446
- package/types/api/BaseEntity.d.ts.map +1 -0
- package/types/api/Comment.d.ts +36 -0
- package/types/api/EndpointApi.d.ts +347 -295
- package/types/api/EndpointApi.d.ts.map +1 -0
- package/types/api/EndpointApi.types.d.ts +3914 -4133
- package/types/api/EntityRegistry.d.ts +18 -16
- package/types/api/EntityRegistry.d.ts.map +1 -0
- package/types/api/Event.d.ts +119 -35
- package/types/api/Event.d.ts.map +1 -0
- package/types/api/News.d.ts +52 -20
- package/types/api/News.d.ts.map +1 -0
- package/types/api/Organization.d.ts +165 -49
- package/types/api/Organization.d.ts.map +1 -0
- package/types/api/Poi.d.ts +51 -22
- package/types/api/Poi.d.ts.map +1 -0
- package/types/api/Project.d.ts +151 -52
- package/types/api/Project.d.ts.map +1 -0
- package/types/api/User.d.ts +222 -93
- package/types/api/User.d.ts.map +1 -0
- package/types/api/UserApi.d.ts +60 -9
- package/types/api/UserApi.d.ts.map +1 -0
- package/types/api/serverDataType/Comment.d.ts +83 -0
- package/types/api/serverDataType/Event.d.ts +67 -0
- package/types/api/serverDataType/News.d.ts +130 -0
- package/types/api/serverDataType/Organization.d.ts +65 -0
- package/types/api/serverDataType/Organization.d.ts.map +1 -0
- package/types/api/serverDataType/Project.d.ts +58 -0
- package/types/api/serverDataType/Project.d.ts.map +1 -0
- package/types/api/serverDataType/User.d.ts +86 -0
- package/types/api/serverDataType/User.d.ts.map +1 -0
- package/types/api/serverDataType/common.d.ts +71 -0
- package/types/api/serverDataType/common.d.ts.map +1 -0
- package/types/endpoints.module.d.ts +6922 -1215
- package/types/endpoints.module.d.ts.map +1 -0
- package/types/error.d.ts +25 -51
- package/types/error.d.ts.map +1 -0
- package/types/index.d.ts +55 -48
- package/types/index.d.ts.map +1 -0
- package/types/mixin/UserMixin.d.ts +1 -1
- package/types/mixin/UserMixin.d.ts.map +1 -0
- package/types/types/api-responses.d.ts +190 -0
- package/types/types/api-responses.d.ts.map +1 -0
- package/types/types/entities.d.ts +17 -0
- package/types/types/entities.d.ts.map +1 -0
- package/types/types/error-guards.d.ts +99 -0
- package/types/types/error-guards.d.ts.map +1 -0
- package/types/types/index.d.ts +7 -0
- package/types/types/payloads.d.ts +17 -0
- package/types/types/payloads.d.ts.map +1 -0
- package/types/types/transforms.d.ts +79 -0
- package/types/types/transforms.d.ts.map +1 -0
- package/types/utils/FileOfflineStorageStrategy.node.d.ts +10 -9
- package/types/utils/FileOfflineStorageStrategy.node.d.ts.map +1 -0
- package/types/utils/FileStorageStrategy.node.d.ts +9 -20
- package/types/utils/FileStorageStrategy.node.d.ts.map +1 -0
- package/types/utils/MultiServerFileStorageStrategy.node.d.ts +13 -18
- package/types/utils/MultiServerFileStorageStrategy.node.d.ts.map +1 -0
- package/types/utils/MultiServerTokenStorageStrategy.d.ts +30 -51
- package/types/utils/MultiServerTokenStorageStrategy.d.ts.map +1 -0
- package/types/utils/OfflineClientManager.d.ts +52 -88
- package/types/utils/OfflineClientManager.d.ts.map +1 -0
- package/types/utils/OfflineQueueStorageStrategy.d.ts +12 -9
- package/types/utils/OfflineQueueStorageStrategy.d.ts.map +1 -0
- package/types/utils/TokenStorage.d.ts +20 -70
- package/types/utils/TokenStorage.d.ts.map +1 -0
- package/types/utils/compat.d.ts +4 -0
- package/types/utils/compat.d.ts.map +1 -0
- package/types/utils/createDefaultMultiServerTokenStorageStrategy.d.ts +2 -11
- package/types/utils/createDefaultMultiServerTokenStorageStrategy.d.ts.map +1 -0
- package/types/utils/createDefaultOfflineStrategy.d.ts +2 -3
- package/types/utils/createDefaultOfflineStrategy.d.ts.map +1 -0
- package/types/utils/createDefaultTokenStorageStrategy.d.ts +2 -12
- package/types/utils/createDefaultTokenStorageStrategy.d.ts.map +1 -0
- package/types/utils/reactive.d.ts +10 -16
- package/types/utils/reactive.d.ts.map +1 -0
- package/types/utils/stream-utils.node.d.ts +3 -2
- package/types/utils/stream-utils.node.d.ts.map +1 -0
- package/dist/123.cocolight-api-client.browser.js +0 -1
- package/dist/123.cocolight-api-client.cjs +0 -1
- package/dist/22.cocolight-api-client.mjs.js +0 -1
- package/dist/339.cocolight-api-client.mjs.js +0 -1
- package/dist/394.cocolight-api-client.browser.js +0 -1
- package/dist/394.cocolight-api-client.cjs +0 -1
- package/dist/405.cocolight-api-client.browser.js +0 -1
- package/dist/405.cocolight-api-client.cjs +0 -1
- package/dist/774.cocolight-api-client.mjs.js +0 -1
- package/dist/790.cocolight-api-client.mjs.js +0 -1
- package/dist/931.cocolight-api-client.browser.js +0 -1
- package/dist/931.cocolight-api-client.cjs +0 -1
- package/src/EJSONType.js +0 -53
- package/src/api/BaseEntity.js +0 -2828
- package/src/api/EntityRegistry.js +0 -152
- package/src/api/Event.js +0 -226
- package/src/api/News.js +0 -244
- package/src/api/UserApi.js +0 -81
- package/src/endpoints.module.js +0 -5
- package/src/error.js +0 -121
- package/src/index.js +0 -97
- package/src/mixin/UserMixin.js +0 -8
- package/src/utils/MultiServerFileStorageStrategy.node.js +0 -87
- package/src/utils/MultiServerTokenStorageStrategy.js +0 -188
- package/src/utils/OfflineQueueStorageStrategy.js +0 -51
- package/src/utils/TokenStorage.js +0 -153
- package/src/utils/createDefaultMultiServerTokenStorageStrategy.js +0 -51
- package/src/utils/createDefaultTokenStorageStrategy.js +0 -49
- package/src/utils/stream-utils.node.js +0 -10
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// TypeScript native types
|
|
2
|
+
import type { CollectionType } from "../types/entities.js";
|
|
3
|
+
|
|
4
|
+
export type EntityTag = "User" | "Organization" | "Project" | "Event" | "Poi" | "Badge" | "News" | "Comment";
|
|
5
|
+
export type CollectionKey = CollectionType; // Alias pour compatibilité
|
|
6
|
+
type BaseEntity = import("./BaseEntity.js").BaseEntity<any>;
|
|
7
|
+
type ApiClient = import("../ApiClient.js").default;
|
|
8
|
+
|
|
9
|
+
type EndpointApiClass = typeof import("./EndpointApi.js").default;
|
|
10
|
+
type EntityConstructor = new (...args: any[]) => BaseEntity;
|
|
11
|
+
type EntityClass = EntityConstructor & {
|
|
12
|
+
fromJSON?: (json: unknown, parent?: ApiClient | BaseEntity | null, deps?: EntityDeps) => BaseEntity;
|
|
13
|
+
};
|
|
14
|
+
type EntityDeps = Partial<Record<EntityTag | "EndpointApi", EntityClass | EndpointApiClass | undefined>>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Métadonnées de construction d'entité.
|
|
18
|
+
*/
|
|
19
|
+
type EntityMeta = {
|
|
20
|
+
entityClass: EntityClass;
|
|
21
|
+
deps: EntityDeps;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Types minimaux pour le JSON d'entité
|
|
26
|
+
*/
|
|
27
|
+
type MinimalEntityJSON = {
|
|
28
|
+
__entityTag: EntityTag;
|
|
29
|
+
serverData?: {
|
|
30
|
+
collection?: CollectionKey;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const EntityRegistry: Map<EntityTag | "EndpointApi", EntityClass | EndpointApiClass> = new Map();
|
|
35
|
+
|
|
36
|
+
// Overloads for registerEntity
|
|
37
|
+
export function registerEntity(tag: "EndpointApi", EntityClass: EndpointApiClass): void;
|
|
38
|
+
export function registerEntity(tag: EntityTag, EntityClass: EntityClass): void;
|
|
39
|
+
export function registerEntity(tag: EntityTag | "EndpointApi", EntityClass: EntityClass | EndpointApiClass): void {
|
|
40
|
+
EntityRegistry.set(tag, EntityClass);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Type guard: vérifie si la valeur ressemble à un JSON d'entité.
|
|
46
|
+
*/
|
|
47
|
+
function isEntityJSON(v: unknown): v is MinimalEntityJSON {
|
|
48
|
+
return !!v && typeof v === "object"
|
|
49
|
+
&& "__entityTag" in (v as any);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Récupère une instance depuis un JSON générique.
|
|
54
|
+
* Si la collection ou la métadonnée d'entité est absente, renvoie l'objet d'origine.
|
|
55
|
+
*/
|
|
56
|
+
export function fromEntityJSON(json: unknown, parent: ApiClient | BaseEntity | null = null): BaseEntity | unknown | null {
|
|
57
|
+
// On gère null / non-objet / pas une entité → on renvoie tel quel (ou null si tu préfères)
|
|
58
|
+
if (!isEntityJSON(json)) return json;
|
|
59
|
+
|
|
60
|
+
// Ici, TS sait que json.__entityTag existe
|
|
61
|
+
if (!json.serverData?.collection) return json;
|
|
62
|
+
|
|
63
|
+
const meta = _getEntityMeta(json.serverData.collection, json.__entityTag);
|
|
64
|
+
if (!meta) return json;
|
|
65
|
+
|
|
66
|
+
if (!meta.entityClass?.fromJSON) {
|
|
67
|
+
throw new Error(`Classe inconnue ou fromJSON manquant pour ${json.__entityTag}`);
|
|
68
|
+
}
|
|
69
|
+
return meta.entityClass.fromJSON(json, parent, meta.deps);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Récupère la classe d'entité et ses dépendances à partir du type d'entité.
|
|
74
|
+
*/
|
|
75
|
+
function _getEntityMeta(entityType: CollectionKey, __entityTag: EntityTag): EntityMeta | null {
|
|
76
|
+
const selfClass = EntityRegistry.get(__entityTag);
|
|
77
|
+
const selfTag = __entityTag;
|
|
78
|
+
|
|
79
|
+
const commonDeps: EntityDeps = {
|
|
80
|
+
EndpointApi: EntityRegistry.get("EndpointApi"),
|
|
81
|
+
User: selfTag === "User" ? selfClass : EntityRegistry.get("User"),
|
|
82
|
+
Organization: selfTag === "Organization" ? selfClass : EntityRegistry.get("Organization"),
|
|
83
|
+
Project: selfTag === "Project" ? selfClass : EntityRegistry.get("Project"),
|
|
84
|
+
Event: selfTag === "Event" ? selfClass : EntityRegistry.get("Event"),
|
|
85
|
+
Poi: selfTag === "Poi" ? selfClass : EntityRegistry.get("Poi"),
|
|
86
|
+
Badge: selfTag === "Badge" ? selfClass : EntityRegistry.get("Badge"),
|
|
87
|
+
News: selfTag === "News" ? selfClass : EntityRegistry.get("News"),
|
|
88
|
+
Comment: selfTag === "Comment" ? selfClass : EntityRegistry.get("Comment"),
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const map: Record<CollectionKey, EntityMeta> = {
|
|
92
|
+
citoyens: { entityClass: commonDeps.User as EntityClass, deps: commonDeps },
|
|
93
|
+
organizations:{ entityClass: commonDeps.Organization as EntityClass, deps: commonDeps },
|
|
94
|
+
projects: { entityClass: commonDeps.Project as EntityClass, deps: commonDeps },
|
|
95
|
+
events: { entityClass: commonDeps.Event as EntityClass, deps: { ...commonDeps, Badge: undefined } },
|
|
96
|
+
poi: { entityClass: commonDeps.Poi as EntityClass, deps: { ...commonDeps, Badge: undefined, News: undefined } },
|
|
97
|
+
news: { entityClass: commonDeps.News as EntityClass, deps: { ...commonDeps } },
|
|
98
|
+
badges: { entityClass: commonDeps.Badge as EntityClass, deps: {
|
|
99
|
+
EndpointApi: commonDeps.EndpointApi,
|
|
100
|
+
User: commonDeps.User,
|
|
101
|
+
Organization: commonDeps.Organization,
|
|
102
|
+
Project: commonDeps.Project
|
|
103
|
+
} },
|
|
104
|
+
comments: { entityClass: commonDeps.Comment as EntityClass, deps: { ...commonDeps } }
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
return map[entityType] || null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
type CollectionMapEntry = {
|
|
111
|
+
entityTag: EntityTag;
|
|
112
|
+
meta: (tag: EntityTag) => EntityMeta;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Crée une instance d'entité basée sur le seul nom de la collection.
|
|
117
|
+
*/
|
|
118
|
+
export function createFromCollection(collection: CollectionKey, parent: ApiClient | BaseEntity | null = null, data: object = {}): BaseEntity | null {
|
|
119
|
+
const _collectionMap: Record<CollectionKey, CollectionMapEntry> = {
|
|
120
|
+
citoyens: {
|
|
121
|
+
entityTag: "User",
|
|
122
|
+
meta: tag => _buildMeta(tag, { remove: [] })
|
|
123
|
+
},
|
|
124
|
+
organizations: {
|
|
125
|
+
entityTag: "Organization",
|
|
126
|
+
meta: tag => _buildMeta(tag, { remove: [] })
|
|
127
|
+
},
|
|
128
|
+
projects: {
|
|
129
|
+
entityTag: "Project",
|
|
130
|
+
meta: tag => _buildMeta(tag, { remove: [] })
|
|
131
|
+
},
|
|
132
|
+
events: {
|
|
133
|
+
entityTag: "Event",
|
|
134
|
+
meta: tag => _buildMeta(tag, { remove: ["Badge"] })
|
|
135
|
+
},
|
|
136
|
+
poi: {
|
|
137
|
+
entityTag: "Poi",
|
|
138
|
+
meta: tag => _buildMeta(tag, { remove: ["Badge","News"] })
|
|
139
|
+
},
|
|
140
|
+
news: {
|
|
141
|
+
entityTag: "News",
|
|
142
|
+
meta: tag => _buildMeta(tag, { remove: [] })
|
|
143
|
+
},
|
|
144
|
+
badges: {
|
|
145
|
+
entityTag: "Badge",
|
|
146
|
+
meta: () => _buildCustomMeta("Badge")
|
|
147
|
+
},
|
|
148
|
+
comments: {
|
|
149
|
+
entityTag: "Comment",
|
|
150
|
+
meta: tag => _buildMeta(tag, { remove: [] })
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
const entry = _collectionMap[collection];
|
|
154
|
+
if (!entry) {
|
|
155
|
+
console.warn(`Collection inconnue : '${collection}'`);
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
const { entityTag, meta } = entry;
|
|
159
|
+
const { entityClass, deps } = meta(entityTag);
|
|
160
|
+
if (!entityClass) {
|
|
161
|
+
throw new Error(`EntityClass introuvable pour ${entityTag}`);
|
|
162
|
+
}
|
|
163
|
+
const Ctor = entityClass as EntityConstructor;
|
|
164
|
+
return new Ctor(parent, data, deps);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Construit entityClass et deps pour une collection standard.
|
|
169
|
+
*/
|
|
170
|
+
function _buildMeta(tag: EntityTag, options: { remove: string[] }): EntityMeta {
|
|
171
|
+
const EntityClass = EntityRegistry.get(tag) as EntityClass;
|
|
172
|
+
const allDeps: EntityDeps = {
|
|
173
|
+
EndpointApi: EntityRegistry.get("EndpointApi"),
|
|
174
|
+
User: EntityRegistry.get("User"),
|
|
175
|
+
Organization: EntityRegistry.get("Organization"),
|
|
176
|
+
Project: EntityRegistry.get("Project"),
|
|
177
|
+
Event: EntityRegistry.get("Event"),
|
|
178
|
+
Poi: EntityRegistry.get("Poi"),
|
|
179
|
+
Badge: EntityRegistry.get("Badge"),
|
|
180
|
+
News: EntityRegistry.get("News"),
|
|
181
|
+
Comment: EntityRegistry.get("Comment"),
|
|
182
|
+
};
|
|
183
|
+
// inject self
|
|
184
|
+
(allDeps as any)[tag] = EntityClass;
|
|
185
|
+
// remove undesired
|
|
186
|
+
options.remove.forEach(dep => delete (allDeps as any)[dep]);
|
|
187
|
+
return { entityClass: EntityClass, deps: allDeps };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Cas spécifique des badges : seules certaines dépendances.
|
|
192
|
+
*/
|
|
193
|
+
function _buildCustomMeta(tag: "Badge"): EntityMeta {
|
|
194
|
+
const EntityClass = EntityRegistry.get(tag) as EntityClass;
|
|
195
|
+
const deps: EntityDeps = {
|
|
196
|
+
EndpointApi: EntityRegistry.get("EndpointApi"),
|
|
197
|
+
User: EntityRegistry.get("User"),
|
|
198
|
+
Organization: EntityRegistry.get("Organization"),
|
|
199
|
+
Project: EntityRegistry.get("Project")
|
|
200
|
+
};
|
|
201
|
+
(deps as any)[tag] = EntityClass;
|
|
202
|
+
return { entityClass: EntityClass, deps };
|
|
203
|
+
}
|
package/src/api/Event.ts
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { ApiError } from "../error.js";
|
|
2
|
+
import { BaseEntity, PaginatorPage } from "./BaseEntity.js";
|
|
3
|
+
import { transformEntityRefs } from "../types/transforms.js";
|
|
4
|
+
|
|
5
|
+
import type { AddEventData, GetAttendeesAdminData, GetAttendeesNoAdminData } from "./EndpointApi.types.js";
|
|
6
|
+
import type { User } from "./User.js";
|
|
7
|
+
import type { EventTransforms } from "../types/transforms.js";
|
|
8
|
+
|
|
9
|
+
type EventItemNormalized = import("./serverDataType/Event.js").EventItemNormalized;
|
|
10
|
+
|
|
11
|
+
export class Event extends BaseEntity<EventItemNormalized> {
|
|
12
|
+
static override entityType = "events";
|
|
13
|
+
static override entityTag = "Event";
|
|
14
|
+
|
|
15
|
+
static override SCHEMA_CONSTANTS: string[] = [
|
|
16
|
+
"ADD_EVENT",
|
|
17
|
+
// "UPDATE_BLOCK_DESCRIPTION",
|
|
18
|
+
// "UPDATE_BLOCK_INFO",
|
|
19
|
+
// "UPDATE_BLOCK_SOCIAL",
|
|
20
|
+
// "UPDATE_BLOCK_LOCALITY",
|
|
21
|
+
"UPDATE_BLOCK_SLUG",
|
|
22
|
+
"PROFIL_IMAGE"
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
static ADD_BLOCKS = new Map([
|
|
26
|
+
["ADD_EVENT", "addEvent"],
|
|
27
|
+
["PROFIL_IMAGE", "updateImageProfil"]
|
|
28
|
+
] as const);
|
|
29
|
+
|
|
30
|
+
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
|
+
["UPDATE_BLOCK_SLUG", "updateSlug"],
|
|
36
|
+
["PROFIL_IMAGE", "updateImageProfil"]
|
|
37
|
+
] as const);
|
|
38
|
+
|
|
39
|
+
override defaultFields: Record<string, any> = {
|
|
40
|
+
typeElement: this.getEntityType()
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
override removeFields: string[] = [
|
|
44
|
+
"typeElement"
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
override transforms: EventTransforms = {
|
|
48
|
+
parent: transformEntityRefs,
|
|
49
|
+
organizer: transformEntityRefs
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
override _add = async (payload: Record<string, any>): Promise<void> => {
|
|
53
|
+
if (!this._calledFromSave) {
|
|
54
|
+
throw new ApiError("utilisation invalide de _add, utilisez save", 400);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
payload.id = this._newId?.();
|
|
58
|
+
if (payload.slug) delete payload.slug;
|
|
59
|
+
|
|
60
|
+
for (const [constant, methodName] of Array.from(Event.ADD_BLOCKS)) {
|
|
61
|
+
const blockData = this._extractChangedFieldsFromSchema(
|
|
62
|
+
this.apiClient,
|
|
63
|
+
constant,
|
|
64
|
+
{ ...payload, ...this.defaultFields },
|
|
65
|
+
() => {}
|
|
66
|
+
);
|
|
67
|
+
if (blockData && Object.keys(blockData).length > 0) {
|
|
68
|
+
const data = await this._invokeBlockMethod(Event.ADD_BLOCKS, methodName, blockData);
|
|
69
|
+
if (!this.id && data?.map?.id) {
|
|
70
|
+
this._draftData.id = data.map.id;
|
|
71
|
+
this._draftData.slug = data.map.slug;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
override _update = async (payload: Record<string, any>): Promise<boolean> => {
|
|
78
|
+
if(!this.isAdmin()){
|
|
79
|
+
throw new ApiError("Vous n'avez pas les droits pour modifier cet événement", 403);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!this._calledFromSave) {
|
|
83
|
+
throw new ApiError("utilisation invalide de _update, utilisez save", 400);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let hasChanged = false;
|
|
87
|
+
|
|
88
|
+
const blockData = this._extractAllValidFieldsFromSchema(
|
|
89
|
+
this.apiClient,
|
|
90
|
+
"ADD_EVENT",
|
|
91
|
+
{ ...payload, ...this.defaultFields },
|
|
92
|
+
() => this.initialDraftData,
|
|
93
|
+
this.removeFields
|
|
94
|
+
);
|
|
95
|
+
if (blockData && Object.keys(blockData).length > 0) {
|
|
96
|
+
await this["addEvent"](blockData);
|
|
97
|
+
hasChanged = true;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (payload.id) delete payload.id;
|
|
101
|
+
|
|
102
|
+
for (const [constant, methodName] of Array.from(Event.UPDATE_BLOCKS)) {
|
|
103
|
+
const blockData = this._extractChangedFieldsFromSchema(
|
|
104
|
+
this.apiClient,
|
|
105
|
+
constant,
|
|
106
|
+
{ ...payload, ...this.defaultFields },
|
|
107
|
+
() => this.initialDraftData,
|
|
108
|
+
this.removeFields
|
|
109
|
+
);
|
|
110
|
+
if (blockData && Object.keys(blockData).length > 0) {
|
|
111
|
+
await this._invokeBlockMethod(Event.UPDATE_BLOCKS, methodName, blockData);
|
|
112
|
+
hasChanged = true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return hasChanged;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
async addEvent(data: Partial<AddEventData> = {}): Promise<unknown> {
|
|
120
|
+
|
|
121
|
+
if (!this.isMe && !data.organizer && this.parent) {
|
|
122
|
+
(data as any).organizer = {};
|
|
123
|
+
(data as any).organizer[`${this.parent.id}`] = {
|
|
124
|
+
type: this.parent.getEntityType(),
|
|
125
|
+
name: (this.parent as any).name
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return this.callIsConnected(() => this.endpointApi.addEvent(data as AddEventData));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
override async getOrganizations(): Promise<never> {
|
|
134
|
+
throw new ApiError(`getOrganizations n'existe pas dans ${this.constructor.name}`, 501);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
override async getProjects(): Promise<never> {
|
|
139
|
+
throw new ApiError(`getProjects n'existe pas dans ${this.constructor.name}`, 501);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
async getEvents(): Promise<never> {
|
|
144
|
+
throw new ApiError(`getEvents - les sous-events ne sont pas encore implémentés dans ${this.constructor.name}`, 501);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
override async getPois(): Promise<never> {
|
|
149
|
+
throw new ApiError(`getPois n'existe pas dans ${this.constructor.name}`, 501);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
override async getBadgesIssuer(): Promise<never> {
|
|
154
|
+
throw new ApiError(`getBadgesIssuer n'existe pas dans ${this.constructor.name}`, 501);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* {@inheritDoc BaseEntity#getNews}
|
|
159
|
+
*
|
|
160
|
+
* Récupère les actualités de l'événement.
|
|
161
|
+
*/
|
|
162
|
+
override async getNews(data: Parameters<BaseEntity<EventItemNormalized>["getNews"]>[0] = {}) {
|
|
163
|
+
return super.getNews(data);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* {@inheritDoc BaseEntity#getSubscribers}
|
|
168
|
+
*
|
|
169
|
+
* Récupère les abonnés de l'événement.
|
|
170
|
+
*/
|
|
171
|
+
override async getSubscribers(data: Parameters<BaseEntity<EventItemNormalized>["getSubscribers"]>[0] = {}) {
|
|
172
|
+
return super.getSubscribers(data);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Récupérer les participants d'un événement.
|
|
177
|
+
* Constant : GET_ATTENDEES_NO_ADMIN
|
|
178
|
+
* @param data - Paramètres (partiels) de recherche/pagination.
|
|
179
|
+
* @param options - Options supplémentaires.
|
|
180
|
+
* @param options.toBeValidated - Indique si les participants doivent être validés.
|
|
181
|
+
* @param options.isAdmin - Indique si l'utilisateur est admin.
|
|
182
|
+
* @param options.isInviting - Indique si l'utilisateur est en attente d'invitation.
|
|
183
|
+
* @param options.roles - Liste des rôles à filtrer.
|
|
184
|
+
* @param isNext - Indique si c'est une recherche suivante (pagination).
|
|
185
|
+
* @returns - Un objet contenant le nombre de participants et la liste des participants.
|
|
186
|
+
* @throws {ApiResponseError} - Si une erreur se produit lors de la récupération des participants.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* // Récupérer tous les participants
|
|
190
|
+
* const participants = await project.getAttendees();
|
|
191
|
+
*
|
|
192
|
+
* // Récupérer les participants avec validation en attente
|
|
193
|
+
* const participantsToBeValidated = await project.getAttendees({}, { toBeValidated: true });
|
|
194
|
+
*
|
|
195
|
+
* // Récupérer les participants avec un rôle spécifique
|
|
196
|
+
* const contributorsWithRole = await project.getAttendees({}, { roles: ["admin"] });
|
|
197
|
+
*
|
|
198
|
+
* // Récupérer les participants administrateurs
|
|
199
|
+
* const adminParticipants = await project.getAttendees({}, { isAdmin: true });
|
|
200
|
+
*
|
|
201
|
+
* // Récupérer les participants en attente d'invitation
|
|
202
|
+
* const invitingParticipants = await project.getAttendees({}, { isInviting: true });
|
|
203
|
+
*
|
|
204
|
+
*/
|
|
205
|
+
async getAttendees(
|
|
206
|
+
data: Partial<GetAttendeesNoAdminData | GetAttendeesAdminData> = {},
|
|
207
|
+
options: {
|
|
208
|
+
toBeValidated?: boolean;
|
|
209
|
+
isAdmin?: boolean;
|
|
210
|
+
isAdminPending?: boolean;
|
|
211
|
+
isInviting?: boolean;
|
|
212
|
+
roles?: any[];
|
|
213
|
+
} = {}
|
|
214
|
+
): Promise<PaginatorPage<User>> {
|
|
215
|
+
data.searchType = this._getDefaultFromEndpoint("GET_ATTENDEES_NO_ADMIN", "searchType") as GetAttendeesNoAdminData["searchType"];
|
|
216
|
+
// data.searchBy = "ALL";
|
|
217
|
+
|
|
218
|
+
const paginator = this._createPaginatorEngine({
|
|
219
|
+
initialData: data,
|
|
220
|
+
finalizer: async (finalData) => {
|
|
221
|
+
|
|
222
|
+
const { toBeValidated, isAdmin, isInviting, isAdminPending, roles = [] } = options;
|
|
223
|
+
|
|
224
|
+
if(this.isMe){
|
|
225
|
+
finalData.pathParams = { type: this.getEntityType(), id: this.id };
|
|
226
|
+
// NOTE : dans le schema je crois que si pas de finalData.filters alors le default ce fait avec finalData.pathParams
|
|
227
|
+
// finalData.filters = {
|
|
228
|
+
// [`links.events.${this.id}`]: { "$exists": true },
|
|
229
|
+
// [`links.events.${this.id}.toBeValidated`]: { "$exists": false },
|
|
230
|
+
// [`links.events.${this.id}.isInviting`]: { "$exists": false }
|
|
231
|
+
// };
|
|
232
|
+
finalData.filters = this._buildLinkFilters(this.id, { linkType: "events", toBeValidated, isAdmin, isAdminPending, isInviting, roles });
|
|
233
|
+
} else {
|
|
234
|
+
delete finalData?.pathParams;
|
|
235
|
+
finalData.filters = this._buildLinkFilters(this.id, { linkType: "events", toBeValidated: false, isAdmin, isInviting, roles });
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const fetchFn = this.isMe
|
|
239
|
+
? () => this.callIsMe(() => this.endpointApi.getAttendeesAdmin(finalData))
|
|
240
|
+
: () => this.endpointApi.getAttendeesNoAdmin(finalData);
|
|
241
|
+
|
|
242
|
+
return fetchFn();
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return paginator.next() as Promise<PaginatorPage<User>>;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
override async project(): Promise<never> {
|
|
250
|
+
throw new ApiError(`project n'existe pas dans ${this.constructor.name}`, 501);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
override async poi(): Promise<never> {
|
|
255
|
+
throw new ApiError(`poi n'existe pas dans ${this.constructor.name}`, 501);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
override async event(): Promise<never> {
|
|
260
|
+
throw new ApiError(`les sous-events ne sont pas encore implémentés dans ${this.constructor.name}`, 501);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
override async badge(): Promise<never> {
|
|
265
|
+
throw new ApiError(`badge n'existe pas dans ${this.constructor.name}`, 501);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* {@inheritDoc BaseEntity#news}
|
|
270
|
+
*
|
|
271
|
+
* Crée une instance de news et la récupère si nécessaire.
|
|
272
|
+
*/
|
|
273
|
+
override async news(newsData: Parameters<BaseEntity<EventItemNormalized>["news"]>[0] = {}) {
|
|
274
|
+
return super.news(newsData);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* ───────────────────────────────
|
|
279
|
+
* Lien utilisateur ↔ event
|
|
280
|
+
* (participation, abonnement)
|
|
281
|
+
* ───────────────────────────────
|
|
282
|
+
*/
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* {@inheritDoc BaseEntity#requestToJoin}
|
|
286
|
+
*
|
|
287
|
+
* Rejoindre l'événement en tant que participant.
|
|
288
|
+
*/
|
|
289
|
+
override async requestToJoin() {
|
|
290
|
+
return super.requestToJoin();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* {@inheritDoc BaseEntity#acceptInvitation}
|
|
295
|
+
*
|
|
296
|
+
* Accepte une invitation à rejoindre l'événement.
|
|
297
|
+
* Cette action valide un lien en attente avec l'option `isInviting`.
|
|
298
|
+
*/
|
|
299
|
+
override async acceptInvitation() {
|
|
300
|
+
return super.acceptInvitation();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* {@inheritDoc BaseEntity#leave}
|
|
305
|
+
*
|
|
306
|
+
* Quitte l'événement, que ce soit en tant que participant ou administrateur.
|
|
307
|
+
* Cette action supprime le lien entre l'utilisateur et l'événement.
|
|
308
|
+
*/
|
|
309
|
+
override async leave() {
|
|
310
|
+
return super.leave();
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* {@inheritDoc BaseEntity#follow}
|
|
315
|
+
*
|
|
316
|
+
* Suivre un événement.
|
|
317
|
+
* Cette action permet à l'utilisateur de suivre un événement.
|
|
318
|
+
*/
|
|
319
|
+
override async follow() {
|
|
320
|
+
return super.follow();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* {@inheritDoc BaseEntity#unfollow}
|
|
325
|
+
*
|
|
326
|
+
* Se désabonne d'un événement.
|
|
327
|
+
*/
|
|
328
|
+
override async unfollow() {
|
|
329
|
+
return super.unfollow();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
}
|