@communecter/cocolight-api-client 1.0.1 → 1.0.4

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.1",
3
+ "version": "1.0.4",
4
4
  "description": "Client Axios simplifié pour l'API cocolight",
5
5
  "repository": {
6
6
  "type": "git",
package/src/ApiClient.js CHANGED
@@ -273,34 +273,110 @@ export default class ApiClient extends EventEmitter {
273
273
  }
274
274
  return obj;
275
275
  }
276
-
276
+
277
277
  _resolveSpecialValuesInPlace(obj) {
278
- // Si l'objet ressemble à un fichier uploadé (détecte la présence d'un stream dans la propriété value), ne rien modifier.
279
- if (obj && typeof obj === "object" && obj.value && typeof obj.value.pipe === "function") {
280
- return obj;
281
- }
282
-
283
278
  const aliasMap = {
284
279
  userId: () => this.userId,
285
280
  accessToken: () => this._accessToken,
286
281
  refreshToken: () => this._refreshToken,
287
- baseURL: () => this._baseURL,
288
- // vous pouvez ajouter d'autres alias ici
282
+ baseURL: () => this._baseURL
283
+ };
284
+
285
+ const resolveString = (str) => {
286
+ if (typeof str !== "string") return str;
287
+ return str.replace(/@(\w+)/g, (_, key) => {
288
+ const fn = aliasMap[key];
289
+ const value = typeof fn === "function" ? fn() : undefined;
290
+ if (value === undefined || value === null) {
291
+ return `@${key}`; // on laisse tel quel si la valeur n'est pas définie
292
+ }
293
+ return value;
294
+ });
289
295
  };
290
296
 
291
- if (typeof obj === "string" && obj.startsWith("@")) {
292
- const varName = obj.slice(1);
293
- return typeof aliasMap[varName] === "function" ? aliasMap[varName]() : obj;
294
- } else if (Array.isArray(obj)) {
295
- for (let i = 0; i < obj.length; i++) {
296
- obj[i] = this._resolveSpecialValuesInPlace(obj[i]);
297
+ // Vérifie si l'objet est un binaire (par exemple un flux ou un Buffer)
298
+ const isBinary = (input) => {
299
+ return input && typeof input === "object" &&
300
+ (typeof input.pipe === "function" || (typeof Buffer !== "undefined" && input instanceof Buffer));
301
+ };
302
+
303
+ // Vérifie si l'objet est un "plain object"
304
+ const isPlainObject = (input) => {
305
+ return Object.prototype.toString.call(input) === "[object Object]";
306
+ };
307
+
308
+ const internal = (input) => {
309
+ // Si c'est un binaire, ne rien modifier
310
+ if (isBinary(input)) {
311
+ return input;
312
+ }
313
+ // Si c'est un tableau, on traite chaque élément
314
+ if (Array.isArray(input)) {
315
+ return input.map(internal);
297
316
  }
317
+ // Si c'est un plain object, on crée un nouvel objet avec remplacement dans les clés et valeurs
318
+ if (isPlainObject(input)) {
319
+ const result = {};
320
+ for (const [key, value] of Object.entries(input)) {
321
+ const resolvedKey = resolveString(key);
322
+ result[resolvedKey] = internal(value);
323
+ }
324
+ return result;
325
+ }
326
+ // Si c'est une string, on applique le remplacement
327
+ if (typeof input === "string") {
328
+ return resolveString(input);
329
+ }
330
+ // Sinon (nombre, booléen, etc.), on retourne la valeur telle quelle
331
+ return input;
332
+ };
333
+
334
+ return internal(obj);
335
+ }
336
+
337
+
338
+ _cleanSchemaLeftoverAlias(obj) {
339
+ // Expression régulière qui détecte n'importe quel alias du type "@quelqueChose"
340
+ const aliasRegex = /@\w+/;
341
+
342
+ if (Array.isArray(obj)) {
343
+ return obj.map(item => this._cleanSchemaLeftoverAlias(item));
298
344
  } else if (obj && typeof obj === "object") {
299
- for (const key in obj) {
300
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
301
- obj[key] = this._resolveSpecialValuesInPlace(obj[key]);
345
+ const newObj = {};
346
+ for (const key of Object.keys(obj)) {
347
+ const val = obj[key];
348
+
349
+ // Si le nom de la clé contient un alias (exemple : "@userId", "@anything"), on ne la copie pas
350
+ if (aliasRegex.test(key)) {
351
+ continue;
302
352
  }
353
+
354
+ // Si la propriété s'appelle "default"
355
+ if (key === "default") {
356
+ // Si la valeur est une chaîne et qu'elle contient un alias, on ne la copie pas
357
+ if (typeof val === "string" && aliasRegex.test(val)) {
358
+ continue;
359
+ }
360
+ // Si la valeur est un objet, on le nettoie récursivement
361
+ if (val && typeof val === "object") {
362
+ const cleanedDefault = this._cleanSchemaLeftoverAlias(val);
363
+ // On ajoute seulement si l'objet nettoyé n'est pas vide
364
+ if (Object.keys(cleanedDefault).length > 0) {
365
+ newObj[key] = cleanedDefault;
366
+ }
367
+ continue;
368
+ }
369
+ }
370
+
371
+ // Si la valeur est une chaîne contenant un alias, on ne la copie pas
372
+ if (typeof val === "string" && aliasRegex.test(val)) {
373
+ continue;
374
+ }
375
+
376
+ // Sinon, on nettoie récursivement la valeur
377
+ newObj[key] = this._cleanSchemaLeftoverAlias(val);
303
378
  }
379
+ return newObj;
304
380
  }
305
381
  return obj;
306
382
  }
@@ -357,8 +433,15 @@ export default class ApiClient extends EventEmitter {
357
433
  // === 1. PathParams ===
358
434
  let resolvedPath = path;
359
435
  if (pathSchema) {
436
+
437
+ // Si auth est "none" et que userId n'est pas défini, on nettoie le schéma
438
+ let schemaToCompile = pathSchema;
439
+ if (auth === "none" && this.userId === null) {
440
+ schemaToCompile = this._cleanSchemaLeftoverAlias(pathSchema);
441
+ }
442
+
360
443
  const pathParams = data.pathParams || {};
361
- const validatePathParams = this._ajv.compile(pathSchema);
444
+ const validatePathParams = this._ajv.compile(schemaToCompile);
362
445
  const valid = validatePathParams(pathParams);
363
446
 
364
447
  if (!valid) {
@@ -377,11 +460,17 @@ export default class ApiClient extends EventEmitter {
377
460
 
378
461
  // === 2. Validation données (request schema) ===
379
462
  if (requestSchema) {
463
+ // Si auth est "none" et que userId n'est pas défini, on nettoie le schéma
464
+ let schemaToCompile = requestSchema;
465
+ if (auth === "none" && this.userId === null) {
466
+ schemaToCompile = this._cleanSchemaLeftoverAlias(requestSchema);
467
+ }
468
+
380
469
  const dataForValidation = { ...data };
381
470
  delete dataForValidation.pathParams;
382
471
  const cleanedData = ApiClient.stripNullsInPlace(dataForValidation);
383
-
384
- const validateRequest = this._ajv.compile(requestSchema);
472
+
473
+ const validateRequest = this._ajv.compile(schemaToCompile);
385
474
  const valid = validateRequest(cleanedData);
386
475
  if (!valid) {
387
476
  this.emit("validationError", { stage: "request", errors: validateRequest.errors });