@communecter/cocolight-api-client 1.0.4 → 1.0.6
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@communecter/cocolight-api-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Client Axios simplifié pour l'API cocolight",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,9 +22,10 @@
|
|
|
22
22
|
"build:browser": "webpack --config webpack.config.standalone.js",
|
|
23
23
|
"build:node": "webpack --config webpack.config.node.js",
|
|
24
24
|
"build:esm": "webpack --config webpack.config.esm.mjs",
|
|
25
|
-
"build": "npm run generate:module && npm run generate:doc && npm run lint:fix && npm run build:browser && npm run build:node && npm run build:esm",
|
|
25
|
+
"build": "npm run generate:module:publish && npm run generate:doc && npm run lint:fix && npm run build:browser && npm run build:node && npm run build:esm",
|
|
26
26
|
"build:publish": "npm run build && npm publish --access public",
|
|
27
27
|
"generate:module": "node ./scripts/transform-json-module.js",
|
|
28
|
+
"generate:module:publish": "node ./scripts/transform-json-module.publish.js",
|
|
28
29
|
"generate:doc": "node ./scripts/generate-doc.js",
|
|
29
30
|
"generate:test": "node ./scripts/generate-tests.js",
|
|
30
31
|
"generate:testdata": "node ./scripts/generate-test-data.js"
|
|
@@ -39,10 +40,10 @@
|
|
|
39
40
|
"author": "Thomas",
|
|
40
41
|
"license": "MIT",
|
|
41
42
|
"files": [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
"dist/",
|
|
44
|
+
"src/",
|
|
45
|
+
"package.json",
|
|
46
|
+
"README.md"
|
|
46
47
|
],
|
|
47
48
|
"peerDependencies": {
|
|
48
49
|
"ajv": "^8.17.1",
|
|
@@ -52,27 +53,29 @@
|
|
|
52
53
|
"ejson": "^2.2.3",
|
|
53
54
|
"events": "^3.3.0",
|
|
54
55
|
"pino": "^9.6.0",
|
|
55
|
-
"pino-pretty": "^13.0.0"
|
|
56
|
+
"pino-pretty": "^13.0.0",
|
|
57
|
+
"jwt-decode": "^4.0.0"
|
|
56
58
|
},
|
|
57
59
|
"devDependencies": {
|
|
60
|
+
"@babel/core": "^7.26.10",
|
|
61
|
+
"@babel/preset-env": "^7.26.9",
|
|
62
|
+
"@eslint/js": "^9.23.0",
|
|
58
63
|
"ajv": "^8.17.1",
|
|
59
64
|
"ajv-formats": "^3.0.1",
|
|
60
65
|
"axios": "^1.4.0",
|
|
61
66
|
"axios-retry": "^4.5.0",
|
|
62
|
-
"
|
|
63
|
-
"events": "^3.3.0",
|
|
64
|
-
"pino": "^9.6.0",
|
|
65
|
-
"pino-pretty": "^13.0.0",
|
|
66
|
-
"@babel/core": "^7.26.10",
|
|
67
|
-
"@babel/preset-env": "^7.26.9",
|
|
68
|
-
"@eslint/js": "^9.23.0",
|
|
67
|
+
"jwt-decode": "^4.0.0",
|
|
69
68
|
"babel-jest": "^29.7.0",
|
|
70
69
|
"babel-loader": "^10.0.0",
|
|
70
|
+
"ejson": "^2.2.3",
|
|
71
71
|
"eslint": "^9.23.0",
|
|
72
72
|
"eslint-plugin-import": "^2.31.0",
|
|
73
|
+
"events": "^3.3.0",
|
|
73
74
|
"globals": "^16.0.0",
|
|
74
75
|
"jest": "^29.7.0",
|
|
75
76
|
"nodemon": "^3.1.9",
|
|
77
|
+
"pino": "^9.6.0",
|
|
78
|
+
"pino-pretty": "^13.0.0",
|
|
76
79
|
"webpack": "^5.98.0",
|
|
77
80
|
"webpack-cli": "^6.0.1"
|
|
78
81
|
}
|
package/src/ApiClient.js
CHANGED
|
@@ -5,6 +5,7 @@ import addFormats from "ajv-formats";
|
|
|
5
5
|
import axios from "axios";
|
|
6
6
|
import axiosRetry from "axios-retry";
|
|
7
7
|
import EJSON from "ejson";
|
|
8
|
+
import { jwtDecode } from "jwt-decode";
|
|
8
9
|
import pino from "pino";
|
|
9
10
|
|
|
10
11
|
import MongoID from "./EJSONType.js";
|
|
@@ -146,6 +147,12 @@ export default class ApiClient extends EventEmitter {
|
|
|
146
147
|
setToken(token) {
|
|
147
148
|
this._accessToken = token;
|
|
148
149
|
this._client.defaults.headers.common["Authorization"] = "Bearer " + token;
|
|
150
|
+
// Extrait l'id depuis le token et le stocke si disponible
|
|
151
|
+
const userId = this._getIdFromToken(token);
|
|
152
|
+
if (userId) {
|
|
153
|
+
this._setUserId(userId);
|
|
154
|
+
this._logger.debug(`[ApiClient] userId extrait et défini : ${userId}`);
|
|
155
|
+
}
|
|
149
156
|
this._logger.debug(`[ApiClient] setToken: ${token}`);
|
|
150
157
|
}
|
|
151
158
|
|
|
@@ -165,6 +172,12 @@ export default class ApiClient extends EventEmitter {
|
|
|
165
172
|
*/
|
|
166
173
|
setRefreshToken(rt) {
|
|
167
174
|
this._refreshToken = rt;
|
|
175
|
+
// Vous pouvez faire de même ici si besoin
|
|
176
|
+
const userId = this._getIdFromToken(rt);
|
|
177
|
+
if (userId) {
|
|
178
|
+
this._setUserId(userId);
|
|
179
|
+
this._logger.debug(`[ApiClient] userId extrait depuis refreshToken : ${userId}`);
|
|
180
|
+
}
|
|
168
181
|
this._logger.debug(`[ApiClient] setRefreshToken: ${rt}`);
|
|
169
182
|
}
|
|
170
183
|
|
|
@@ -177,6 +190,26 @@ export default class ApiClient extends EventEmitter {
|
|
|
177
190
|
return this._refreshToken;
|
|
178
191
|
}
|
|
179
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Extrait l'identifiant depuis un JWT.
|
|
195
|
+
*
|
|
196
|
+
* @param {string} token - Le token JWT (accessToken ou refreshToken).
|
|
197
|
+
* @returns {string|null} L'identifiant extrait ou null si non trouvé.
|
|
198
|
+
*/
|
|
199
|
+
_getIdFromToken(token) {
|
|
200
|
+
if (!token) return null;
|
|
201
|
+
try {
|
|
202
|
+
// Décodage du token grâce à jwt-decode
|
|
203
|
+
const payload = jwtDecode(token);
|
|
204
|
+
// L'identifiant peut être dans "id" ou "userId"
|
|
205
|
+
this._logger.log("[ApiClient] Payload décodé :", payload);
|
|
206
|
+
return payload.id || payload.userId || null;
|
|
207
|
+
} catch (err) {
|
|
208
|
+
this._logger.error("[ApiClient] Erreur lors du décodage du token :", err.message);
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
180
213
|
/**
|
|
181
214
|
* Méthode simplifiée de refresh (en JSON).
|
|
182
215
|
* Emet un event refreshSuccess si ça marche
|
|
@@ -274,25 +307,69 @@ export default class ApiClient extends EventEmitter {
|
|
|
274
307
|
return obj;
|
|
275
308
|
}
|
|
276
309
|
|
|
277
|
-
_resolveSpecialValuesInPlace(obj) {
|
|
310
|
+
_resolveSpecialValuesInPlace(obj, pathParams = {}) {
|
|
278
311
|
const aliasMap = {
|
|
279
312
|
userId: () => this.userId,
|
|
280
313
|
accessToken: () => this._accessToken,
|
|
281
314
|
refreshToken: () => this._refreshToken,
|
|
282
|
-
baseURL: () => this._baseURL
|
|
315
|
+
baseURL: () => this._baseURL,
|
|
316
|
+
pathParams: (subPath) => {
|
|
317
|
+
// Si la valeur existe dans pathParams, on la retourne
|
|
318
|
+
const value = this._getValueByPath(pathParams, subPath);
|
|
319
|
+
return value !== undefined && value !== null ? value : undefined;
|
|
320
|
+
}
|
|
283
321
|
};
|
|
284
322
|
|
|
323
|
+
// Expression régulière qui capture les alias sous forme délimitée @{...} ou simple @...
|
|
324
|
+
const regex = /@(?:\{([^}]+)\}|([\w.]+))/g;
|
|
325
|
+
|
|
285
326
|
const resolveString = (str) => {
|
|
286
327
|
if (typeof str !== "string") return str;
|
|
287
|
-
return str.replace(
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
328
|
+
return str.replace(regex, (_, delimitedAlias, plainAlias) => {
|
|
329
|
+
// Si alias délimité, on traite toute la chaîne à l'intérieur des accolades.
|
|
330
|
+
if (delimitedAlias) {
|
|
331
|
+
// On s'attend à une forme comme "pathParams.id.autre"
|
|
332
|
+
if (delimitedAlias.startsWith("pathParams.")) {
|
|
333
|
+
const subPath = delimitedAlias.substring("pathParams.".length);
|
|
334
|
+
const value = aliasMap.pathParams(subPath);
|
|
335
|
+
return value !== undefined && value !== null ? value : `@{${delimitedAlias}}`;
|
|
336
|
+
} else {
|
|
337
|
+
// Pour d'autres alias délimités, on cherche directement dans aliasMap
|
|
338
|
+
const fn = aliasMap[delimitedAlias];
|
|
339
|
+
if (typeof fn === "function") {
|
|
340
|
+
const value = fn();
|
|
341
|
+
return value !== undefined && value !== null ? value : `@{${delimitedAlias}}`;
|
|
342
|
+
}
|
|
343
|
+
return `@{${delimitedAlias}}`;
|
|
344
|
+
}
|
|
345
|
+
} else if (plainAlias) {
|
|
346
|
+
// Traitement de l'alias simple, potentiellement avec des segments
|
|
347
|
+
// Vérifier s'il commence par "pathParams."
|
|
348
|
+
if (plainAlias.startsWith("pathParams.")) {
|
|
349
|
+
// Extrait la partie après "pathParams." et sépare le premier segment et le reste.
|
|
350
|
+
const match = plainAlias.match(/^pathParams\.([^.]+)(.*)$/);
|
|
351
|
+
if (match) {
|
|
352
|
+
const subKey = match[1]; // ex: "id"
|
|
353
|
+
const remainder = match[2]; // ex: "" ou ".autrechose"
|
|
354
|
+
// Si le reste est vide, ou s'il ne doit pas être remplacé (on remplace toujours le premier segment uniquement)
|
|
355
|
+
const value = aliasMap.pathParams(subKey);
|
|
356
|
+
return value !== undefined && value !== null ? value + remainder : `@${plainAlias}`;
|
|
357
|
+
}
|
|
358
|
+
return `@${plainAlias}`;
|
|
359
|
+
} else {
|
|
360
|
+
// Pour tout autre alias simple sans point ou autre
|
|
361
|
+
const fn = aliasMap[plainAlias];
|
|
362
|
+
if (typeof fn === "function") {
|
|
363
|
+
const value = fn();
|
|
364
|
+
return value !== undefined && value !== null ? value : `@${plainAlias}`;
|
|
365
|
+
}
|
|
366
|
+
return `@${plainAlias}`;
|
|
367
|
+
}
|
|
292
368
|
}
|
|
293
|
-
return
|
|
369
|
+
return str;
|
|
294
370
|
});
|
|
295
371
|
};
|
|
372
|
+
|
|
296
373
|
|
|
297
374
|
// Vérifie si l'objet est un binaire (par exemple un flux ou un Buffer)
|
|
298
375
|
const isBinary = (input) => {
|
|
@@ -432,6 +509,7 @@ export default class ApiClient extends EventEmitter {
|
|
|
432
509
|
|
|
433
510
|
// === 1. PathParams ===
|
|
434
511
|
let resolvedPath = path;
|
|
512
|
+
let resolvedParams = {};
|
|
435
513
|
if (pathSchema) {
|
|
436
514
|
|
|
437
515
|
// Si auth est "none" et que userId n'est pas défini, on nettoie le schéma
|
|
@@ -449,7 +527,7 @@ export default class ApiClient extends EventEmitter {
|
|
|
449
527
|
throw new ApiClientError("Path parameter validation failed.", 400, validatePathParams.errors);
|
|
450
528
|
}
|
|
451
529
|
|
|
452
|
-
|
|
530
|
+
resolvedParams = this._resolveSpecialValuesInPlace(pathParams);
|
|
453
531
|
|
|
454
532
|
resolvedPath = resolvedPath.replace(/\{(\w+)\}/g, (_, key) => {
|
|
455
533
|
const val = resolvedParams[key];
|
|
@@ -477,7 +555,7 @@ export default class ApiClient extends EventEmitter {
|
|
|
477
555
|
throw new ApiClientError("Request validation failed.", 400, validateRequest.errors);
|
|
478
556
|
}
|
|
479
557
|
|
|
480
|
-
data = this._resolveSpecialValuesInPlace(cleanedData);
|
|
558
|
+
data = this._resolveSpecialValuesInPlace(cleanedData, resolvedParams);
|
|
481
559
|
}
|
|
482
560
|
|
|
483
561
|
// === 3. Payload ===
|
|
@@ -533,9 +611,9 @@ export default class ApiClient extends EventEmitter {
|
|
|
533
611
|
this.setRefreshToken(value);
|
|
534
612
|
break;
|
|
535
613
|
|
|
536
|
-
|
|
537
|
-
this._setUserId(value);
|
|
538
|
-
break;
|
|
614
|
+
// case "setUserId":
|
|
615
|
+
// this._setUserId(value);
|
|
616
|
+
// break;
|
|
539
617
|
|
|
540
618
|
case "resetSession":
|
|
541
619
|
this.resetSession();
|
|
@@ -910,28 +988,28 @@ export default class ApiClient extends EventEmitter {
|
|
|
910
988
|
* @param {Object} obj - L’objet à normaliser.
|
|
911
989
|
* @returns {Object} L’objet normalisé.
|
|
912
990
|
*/
|
|
913
|
-
_normalizeDatesRecursively(obj) {
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
}
|
|
991
|
+
// _normalizeDatesRecursively(obj) {
|
|
992
|
+
// if (obj === null || typeof obj !== "object") return obj;
|
|
993
|
+
|
|
994
|
+
// // Si c'est un tableau, on traite chaque élément récursivement.
|
|
995
|
+
// if (Array.isArray(obj)) {
|
|
996
|
+
// return obj.map(item => this._normalizeDatesRecursively(item));
|
|
997
|
+
// }
|
|
998
|
+
|
|
999
|
+
// Object.keys(obj).forEach((key) => {
|
|
1000
|
+
// if (this._dateFields.includes(key)) {
|
|
1001
|
+
// if (obj[key] && typeof obj[key] === "object" && obj[key].sec && typeof obj[key].sec === "number") {
|
|
1002
|
+
// obj[key] = { $date: obj[key].sec * 1000 };
|
|
1003
|
+
// } else if (typeof obj[key] === "number") {
|
|
1004
|
+
// obj[key] = { $date: obj[key] * 1000 };
|
|
1005
|
+
// }
|
|
1006
|
+
// }
|
|
1007
|
+
// if (obj[key] && typeof obj[key] === "object") {
|
|
1008
|
+
// this._normalizeDatesRecursively(obj[key]);
|
|
1009
|
+
// }
|
|
1010
|
+
// });
|
|
1011
|
+
// return obj;
|
|
1012
|
+
// }
|
|
935
1013
|
|
|
936
1014
|
/**
|
|
937
1015
|
* Parcourt récursivement un objet pour normaliser les chemins d'images.
|
|
@@ -942,30 +1020,30 @@ export default class ApiClient extends EventEmitter {
|
|
|
942
1020
|
* @param {Object} obj - L’objet à normaliser.
|
|
943
1021
|
* @returns {Object} L’objet normalisé.
|
|
944
1022
|
*/
|
|
945
|
-
_normalizeImagesRecursively(obj) {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
}
|
|
1023
|
+
// _normalizeImagesRecursively(obj) {
|
|
1024
|
+
// if (obj === null || typeof obj !== "object") return obj;
|
|
1025
|
+
|
|
1026
|
+
// // Si c'est un tableau, on traite chaque élément récursivement.
|
|
1027
|
+
// if (Array.isArray(obj)) {
|
|
1028
|
+
// return obj.map(item => this._normalizeImagesRecursively(item));
|
|
1029
|
+
// }
|
|
1030
|
+
|
|
1031
|
+
// Object.keys(obj).forEach((key) => {
|
|
1032
|
+
// if (this._imageFields.includes(key) && typeof obj[key] === "string" && obj[key].trim() !== "") {
|
|
1033
|
+
// obj[key] = this._ensureFullURL(obj[key]);
|
|
1034
|
+
// }
|
|
1035
|
+
|
|
1036
|
+
// // Cas particulier pour content.image
|
|
1037
|
+
// if (key === "content" && obj[key]?.image) {
|
|
1038
|
+
// obj[key].image = this._ensureFullURL(obj[key].image);
|
|
1039
|
+
// }
|
|
1040
|
+
|
|
1041
|
+
// if (obj[key] && typeof obj[key] === "object") {
|
|
1042
|
+
// this._normalizeImagesRecursively(obj[key]);
|
|
1043
|
+
// }
|
|
1044
|
+
// });
|
|
1045
|
+
// return obj;
|
|
1046
|
+
// }
|
|
969
1047
|
|
|
970
1048
|
/**
|
|
971
1049
|
* Parcourt récursivement un objet ou un tableau pour normaliser les identifiants (ID).
|
|
@@ -975,33 +1053,33 @@ export default class ApiClient extends EventEmitter {
|
|
|
975
1053
|
* @param {Object|Array} obj - L'objet ou le tableau à normaliser.
|
|
976
1054
|
* @returns {Object|Array} L'objet ou le tableau normalisé.
|
|
977
1055
|
*/
|
|
978
|
-
_normalizeIdRecursively(obj) {
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
}
|
|
1056
|
+
// _normalizeIdRecursively(obj) {
|
|
1057
|
+
// if (obj === null || typeof obj !== "object") return obj;
|
|
1058
|
+
|
|
1059
|
+
// // Si c'est un tableau, on traite chaque élément récursivement.
|
|
1060
|
+
// if (Array.isArray(obj)) {
|
|
1061
|
+
// return obj.map(item => this._normalizeIdRecursively(item));
|
|
1062
|
+
// }
|
|
1063
|
+
|
|
1064
|
+
// // Vérifier et normaliser l'ID dans l'objet
|
|
1065
|
+
// if (obj._id && obj._id.$id && /^[0-9a-fA-F]{24}$/.test(obj._id.$id)) {
|
|
1066
|
+
// obj.id = obj._id.$id;
|
|
1067
|
+
// obj._id = { $type: "oid", $value: obj._id.$id };
|
|
1068
|
+
// }
|
|
1069
|
+
// if (obj.id && obj.id.$id && /^[0-9a-fA-F]{24}$/.test(obj.id.$id)) {
|
|
1070
|
+
// obj._id = { $type: "oid", $value: obj.id.$id };
|
|
1071
|
+
// obj.id = obj.id.$id;
|
|
1072
|
+
// }
|
|
1073
|
+
|
|
1074
|
+
// // Appel récursif pour chaque propriété de l'objet
|
|
1075
|
+
// Object.keys(obj).forEach(key => {
|
|
1076
|
+
// if (obj[key] && typeof obj[key] === "object") {
|
|
1077
|
+
// obj[key] = this._normalizeIdRecursively(obj[key]);
|
|
1078
|
+
// }
|
|
1079
|
+
// });
|
|
1080
|
+
|
|
1081
|
+
// return obj;
|
|
1082
|
+
// }
|
|
1005
1083
|
|
|
1006
1084
|
/**
|
|
1007
1085
|
* Normalise récursivement les valeurs booléennes.
|
|
@@ -1010,22 +1088,22 @@ export default class ApiClient extends EventEmitter {
|
|
|
1010
1088
|
* @param {any} data - L'objet, le tableau ou la valeur à normaliser.
|
|
1011
1089
|
* @returns {any} La donnée normalisée.
|
|
1012
1090
|
*/
|
|
1013
|
-
_normalizeBooleansRecursively(data) {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
}
|
|
1091
|
+
// _normalizeBooleansRecursively(data) {
|
|
1092
|
+
// if (typeof data === "string") {
|
|
1093
|
+
// if (data === "true") return true;
|
|
1094
|
+
// if (data === "false") return false;
|
|
1095
|
+
// return data;
|
|
1096
|
+
// }
|
|
1097
|
+
// if (Array.isArray(data)) {
|
|
1098
|
+
// return data.map(item => this._normalizeBooleansRecursively(item));
|
|
1099
|
+
// }
|
|
1100
|
+
// if (data !== null && typeof data === "object") {
|
|
1101
|
+
// Object.keys(data).forEach(key => {
|
|
1102
|
+
// data[key] = this._normalizeBooleansRecursively(data[key]);
|
|
1103
|
+
// });
|
|
1104
|
+
// }
|
|
1105
|
+
// return data;
|
|
1106
|
+
// }
|
|
1029
1107
|
|
|
1030
1108
|
/**
|
|
1031
1109
|
* Transforme une chaîne "true" ou "false" en booléen.
|