@communecter/cocolight-api-client 1.0.122 → 1.0.124

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.
@@ -0,0 +1,171 @@
1
+ import { ApiError } from "../error.js";
2
+ import { BaseEntity } from "./BaseEntity.js";
3
+ import { transformEntityRefs } from "../types/transforms.js";
4
+
5
+ import type { AddClassifiedData } from "./EndpointApi.types.js";
6
+ import type { ClassifiedItemNormalized } from "./serverDataType/Classified.js";
7
+
8
+ export class Classified extends BaseEntity<ClassifiedItemNormalized> {
9
+ static override entityType = "classifieds";
10
+
11
+ static override entityTag = "Classified";
12
+
13
+ static override SCHEMA_CONSTANTS: string[] = [
14
+ "ADD_CLASSIFIED",
15
+ ];
16
+
17
+ static ADD_BLOCKS = new Map([
18
+ ["ADD_CLASSIFIED", "addClassified"],
19
+ ] as const);
20
+
21
+ override defaultFields: Record<string, unknown> = {
22
+ typeElement: "classified",
23
+ };
24
+
25
+ override removeFields: string[] = [
26
+ "typeElement",
27
+ ];
28
+
29
+ // Le serveur enrichit `parent` avec _id/slug/id/profilThumbImageUrl/etc.
30
+ // qui ne sont pas dans le schéma d'envoi (additionalProperties: false → name, type seuls).
31
+ // On filtre via transformEntityRefs à la construction du draft pour rester compatible
32
+ // côté update (pattern identique à Event.transforms).
33
+ override transforms: Record<string, (val: any, full?: any) => any> = {
34
+ parent: transformEntityRefs,
35
+ };
36
+
37
+ override _add = async (payload: Record<string, unknown>): Promise<void> => {
38
+ if (!this._calledFromSave) {
39
+ throw new ApiError("utilisation invalide de _add, utilisez save", 400);
40
+ }
41
+
42
+ payload.id = this._newId?.();
43
+ // if (payload.slug) delete payload.slug;
44
+
45
+ for (const [constant, methodName] of Array.from(Classified.ADD_BLOCKS)) {
46
+ const blockData = this._extractChangedFieldsFromSchema(
47
+ this.apiClient,
48
+ constant,
49
+ { ...payload, ...this.defaultFields },
50
+ () => {}
51
+ );
52
+ if (blockData && Object.keys(blockData).length > 0) {
53
+ const data = await (this as any)[methodName](blockData);
54
+ if (!this.id && data?.map?.id) {
55
+ this._draftData.id = data.map.id;
56
+ this._draftData.slug = data.map.slug;
57
+ }
58
+ }
59
+ }
60
+ };
61
+
62
+ // L'endpoint /co2/element/save (ADD_CLASSIFIED) gère création ET mise à jour selon que
63
+ // l'id existe ou pas côté serveur. On réutilise donc le même schéma pour valider les
64
+ // champs en update (pattern identique à Event._update).
65
+ // Droit de modifier : auteur du classified OU admin d'un parent (orga/projet) si le
66
+ // classified est rattaché.
67
+ override _update = async (payload: Record<string, unknown>): Promise<boolean> => {
68
+ if (!this._calledFromSave) {
69
+ throw new ApiError("utilisation invalide de _update, utilisez save", 400);
70
+ }
71
+ if (!this.isAuthor() && !this.isAdmin({ checkHierarchy: true })) {
72
+ throw new ApiError("Vous n'êtes pas autorisé à modifier cette ressource", 403);
73
+ }
74
+
75
+ let hasChanged = false;
76
+
77
+ const blockData = this._extractAllValidFieldsFromSchema(
78
+ this.apiClient,
79
+ "ADD_CLASSIFIED",
80
+ { ...payload, ...this.defaultFields },
81
+ () => this.initialDraftData,
82
+ this.removeFields
83
+ );
84
+ if (blockData && Object.keys(blockData).length > 0) {
85
+ await this.addClassified(blockData);
86
+ hasChanged = true;
87
+ }
88
+
89
+ return hasChanged;
90
+ };
91
+
92
+ async addClassified(data: Partial<AddClassifiedData> = {}): Promise<unknown> {
93
+ // Si le parent direct n'est pas l'utilisateur connecté (ex: création via une org),
94
+ // on injecte le parent dans le payload. Sans ça, le default schéma `{ "@userId": ... }`
95
+ // pose me comme parent — ce qui est faux pour `me.org().classified()`.
96
+ // NB: this.isMe est trompeur ici car userContext propage jusqu'au User connecté
97
+ // (donc isMe=true même quand le parent direct est une org).
98
+ // Si le caller fournit déjà `data.parent`, on respecte sa valeur (pas de merge automatique).
99
+ const parentData = data as Record<string, unknown>;
100
+ if (this.parent && this.parent.id && this.parent.id !== this.userId && !parentData.parent) {
101
+ parentData.parent = {};
102
+ const parentMap = parentData.parent as Record<string, unknown>;
103
+ parentMap[`${this.parent.id}`] = {
104
+ type: this.parent.getEntityType(),
105
+ name: (this.parent as unknown as Record<string, unknown>).name,
106
+ };
107
+ }
108
+
109
+ return this.callIsConnected(() => this.endpointApi.addClassified(data as AddClassifiedData));
110
+ }
111
+
112
+ override async getOrganizations(): Promise<never> {
113
+ throw new ApiError(`getOrganizations n'existe pas dans ${this.constructor.name}`, 501);
114
+ }
115
+
116
+ override async getProjects(): Promise<never> {
117
+ throw new ApiError(`getProjects n'existe pas dans ${this.constructor.name}`, 501);
118
+ }
119
+
120
+ override async getEvents(): Promise<never> {
121
+ throw new ApiError(`getEvents n'existe pas dans ${this.constructor.name}`, 501);
122
+ }
123
+
124
+ override async getPois(): Promise<never> {
125
+ throw new ApiError(`getPois n'existe pas dans ${this.constructor.name}`, 501);
126
+ }
127
+
128
+ override async getBadgesIssuer(): Promise<never> {
129
+ throw new ApiError(`getBadgesIssuer n'existe pas dans ${this.constructor.name}`, 501);
130
+ }
131
+
132
+ override async getNews(): Promise<never> {
133
+ throw new ApiError(`getNews n'existe pas dans ${this.constructor.name}`, 501);
134
+ }
135
+
136
+ override async project(): Promise<never> {
137
+ throw new ApiError(`project n'existe pas dans ${this.constructor.name}`, 501);
138
+ }
139
+
140
+ override async poi(): Promise<never> {
141
+ throw new ApiError(`poi n'existe pas dans ${this.constructor.name}`, 501);
142
+ }
143
+
144
+ override async event(): Promise<never> {
145
+ throw new ApiError(`event n'existe pas dans ${this.constructor.name}`, 501);
146
+ }
147
+
148
+ override async badge(): Promise<never> {
149
+ throw new ApiError(`badge n'existe pas dans ${this.constructor.name}`, 501);
150
+ }
151
+
152
+ override async news(): Promise<never> {
153
+ throw new ApiError(`news n'existe pas dans ${this.constructor.name}`, 501);
154
+ }
155
+
156
+ override async classified(): Promise<never> {
157
+ throw new ApiError(`classified n'existe pas dans ${this.constructor.name}`, 501);
158
+ }
159
+
160
+ override async follow(): Promise<never> {
161
+ throw new ApiError(`follow n'existe pas dans ${this.constructor.name}`, 501);
162
+ }
163
+
164
+ override async unfollow(): Promise<never> {
165
+ throw new ApiError(`unfollow n'existe pas dans ${this.constructor.name}`, 501);
166
+ }
167
+
168
+ override async getGallery(): Promise<never> {
169
+ throw new ApiError(`getGallery n'existe pas dans ${this.constructor.name}`, 501);
170
+ }
171
+ }