@ix-xs/metamob.api 3.0.0 → 3.0.2

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/README.md CHANGED
@@ -44,6 +44,11 @@
44
44
  - [Recherche d'utilisateurs](#recherche-dutilisateurs)
45
45
  - [Profils utilisateurs](#profils-utilisateurs)
46
46
  - [Quêtes utilisateurs](#quêtes-utilisateurs)
47
+ - [Détails d'une quête utilisateur](#détails-dune-quête-utilisateur)
48
+ - [Partenaires d'échange](#partenaires-déchange)
49
+ - [Modifier les paramètres d'une quête utilisateur](#modifier-les-paramètres-dune-quête-utilisateur)
50
+ - [Modifier plusieurs monstres d'une quête utilisateur](#modifier-plusieurs-monstres-dune-quête-utilisateur)
51
+ - [Paramètres de trade manuels d'une quête utilisateur](#paramètres-de-trade-manuels-dune-quête-utilisateur)
47
52
 
48
53
  ## ✨ Présentation
49
54
 
@@ -247,11 +252,11 @@ getGameVersions(options?: { game_name?: string })
247
252
  const response = await client.getGameVersions();
248
253
 
249
254
  if (!response.ok) {
250
- return console.error(response.error ?? response.statusText);
255
+ return console.error(response.error ?? response.statusText);
251
256
  }
252
257
 
253
258
  response.data.forEach((version) => {
254
- console.log(`${version.id}: ${version.name}`);
259
+ console.log(`${version.id}: ${version.name}`);
255
260
  });
256
261
  // Output:
257
262
  // 1: Dofus (Unity)
@@ -263,12 +268,12 @@ response.data.forEach((version) => {
263
268
 
264
269
  ```javascript
265
270
  const response = await client.getGameVersions({
266
- game_name: "Dofus (Unity)",
271
+ game_name: "Dofus (Unity)",
267
272
  });
268
273
 
269
274
  if (response.ok) {
270
- console.log(response.data);
271
- // { id: 1, name: "Dofus (Unity)" }
275
+ console.log(response.data);
276
+ // { id: 1, name: "Dofus (Unity)" }
272
277
  }
273
278
  ```
274
279
 
@@ -329,11 +334,11 @@ getServers(options?: { server_name?: string })
329
334
  const response = await client.getServers();
330
335
 
331
336
  if (response.ok) {
332
- response.data.forEach((server) => {
333
- console.log(
334
- `${server.name} (${server.community}) - ${server.game_version.name}`,
335
- );
336
- });
337
+ response.data.forEach((server) => {
338
+ console.log(
339
+ `${server.name} (${server.community}) - ${server.game_version.name}`,
340
+ );
341
+ });
337
342
  }
338
343
  ```
339
344
 
@@ -341,17 +346,17 @@ if (response.ok) {
341
346
 
342
347
  ```javascript
343
348
  const response = await client.getServers({
344
- server_name: "Brial",
349
+ server_name: "Brial",
345
350
  });
346
351
 
347
352
  if (response.ok) {
348
- console.log(response.data);
349
- // {
350
- // id: 1,
351
- // name: "Brial",
352
- // community: "France",
353
- // game_version: { id: 1, name: "Dofus (Unity)" }
354
- // }
353
+ console.log(response.data);
354
+ // {
355
+ // id: 1,
356
+ // name: "Brial",
357
+ // community: "France",
358
+ // game_version: { id: 1, name: "Dofus (Unity)" }
359
+ // }
355
360
  }
356
361
  ```
357
362
 
@@ -361,17 +366,17 @@ if (response.ok) {
361
366
  const response = await client.getServers();
362
367
 
363
368
  if (response.ok) {
364
- const byRegion = response.data.reduce((acc, server) => {
365
- if (!acc[server.community]) acc[server.community] = [];
366
- acc[server.community].push(server.name);
367
- return acc;
368
- }, {});
369
-
370
- console.log(byRegion);
371
- // {
372
- // France: ["Brial", "Rafal", ...],
373
- // World: ["Brial", "Rafal", ...]
374
- // }
369
+ const byRegion = response.data.reduce((acc, server) => {
370
+ if (!acc[server.community]) acc[server.community] = [];
371
+ acc[server.community].push(server.name);
372
+ return acc;
373
+ }, {});
374
+
375
+ console.log(byRegion);
376
+ // {
377
+ // France: ["Brial", "Rafal", ...],
378
+ // World: ["Brial", "Rafal", ...]
379
+ // }
375
380
  }
376
381
  ```
377
382
 
@@ -416,11 +421,11 @@ getMonsterTypes(options?: { type_name?: string })
416
421
  const response = await client.getMonsterTypes();
417
422
 
418
423
  if (response.ok) {
419
- response.data.forEach((type) => {
420
- console.log(
421
- `FR: ${type.name.fr}, EN: ${type.name.en}, ES: ${type.name.es}`,
422
- );
423
- });
424
+ response.data.forEach((type) => {
425
+ console.log(
426
+ `FR: ${type.name.fr}, EN: ${type.name.en}, ES: ${type.name.es}`,
427
+ );
428
+ });
424
429
  }
425
430
  ```
426
431
 
@@ -428,15 +433,15 @@ if (response.ok) {
428
433
 
429
434
  ```javascript
430
435
  const response = await client.getMonsterTypes({
431
- type_name: "boss",
436
+ type_name: "boss",
432
437
  });
433
438
 
434
439
  if (response.ok) {
435
- console.log(response.data);
436
- // {
437
- // id: 3,
438
- // name: { fr: "Boss", en: "Boss", es: "Boss" }
439
- // }
440
+ console.log(response.data);
441
+ // {
442
+ // id: 3,
443
+ // name: { fr: "Boss", en: "Boss", es: "Boss" }
444
+ // }
440
445
  }
441
446
  ```
442
447
 
@@ -483,12 +488,12 @@ getQuestTemplates(options?: {
483
488
  const response = await client.getQuestTemplates();
484
489
 
485
490
  if (response.ok) {
486
- console.log(`Modèles trouvés: ${response.pagination.total}`);
487
- response.data.forEach((template) => {
488
- console.log(
489
- `${template.game_version.name}: ${template.monster_count} monstres en ${template.step_count} étapes`,
490
- );
491
- });
491
+ console.log(`Modèles trouvés: ${response.pagination.total}`);
492
+ response.data.forEach((template) => {
493
+ console.log(
494
+ `${template.game_version.name}: ${template.monster_count} monstres en ${template.step_count} étapes`,
495
+ );
496
+ });
492
497
  }
493
498
  ```
494
499
 
@@ -496,16 +501,16 @@ if (response.ok) {
496
501
 
497
502
  ```javascript
498
503
  const response = await client.getQuestTemplates({
499
- game_name: "Dofus (Unity)",
500
- step: 1,
501
- limit: 50,
504
+ game_name: "Dofus (Unity)",
505
+ step: 1,
506
+ limit: 50,
502
507
  });
503
508
 
504
509
  if (response.ok) {
505
- console.log(`Étape 1 - Monstres à capturer:`);
506
- response.data.monsters.forEach((monster) => {
507
- console.log(`- ${monster.name.fr} (étape ${monster.step})`);
508
- });
510
+ console.log(`Étape 1 - Monstres à capturer:`);
511
+ response.data.monsters.forEach((monster) => {
512
+ console.log(`- ${monster.name.fr} (étape ${monster.step})`);
513
+ });
509
514
  }
510
515
  ```
511
516
 
@@ -513,14 +518,14 @@ if (response.ok) {
513
518
 
514
519
  ```javascript
515
520
  const response = await client.getQuestTemplates({
516
- game_name: "Dofus (Unity)",
517
- step: 1,
518
- limit: 10,
519
- offset: 20, // Sauter les 20 premiers résultats
521
+ game_name: "Dofus (Unity)",
522
+ step: 1,
523
+ limit: 10,
524
+ offset: 20, // Sauter les 20 premiers résultats
520
525
  });
521
526
 
522
527
  if (response.ok) {
523
- console.log(`Résultats 21-30 sur ${response.pagination.total}`);
528
+ console.log(`Résultats 21-30 sur ${response.pagination.total}`);
524
529
  }
525
530
  ```
526
531
 
@@ -578,11 +583,11 @@ searchUsers(
578
583
  const response = await client.searchUsers("jean");
579
584
 
580
585
  if (!response.ok) {
581
- return console.error(response.error);
586
+ return console.error(response.error);
582
587
  }
583
588
 
584
589
  response.data.forEach((user) => {
585
- console.log(`${user.username} (${user.avatar.name.fr})`);
590
+ console.log(`${user.username} (${user.avatar.name.fr})`);
586
591
  });
587
592
  ```
588
593
 
@@ -590,16 +595,16 @@ response.data.forEach((user) => {
590
595
 
591
596
  ```javascript
592
597
  const response = await client.searchUsers("jean", {
593
- server_name: "Brial",
594
- active_within_days: 30, // Actifs dans les 30 derniers jours
595
- limit: 10,
598
+ server_name: "Brial",
599
+ active_within_days: 30, // Actifs dans les 30 derniers jours
600
+ limit: 10,
596
601
  });
597
602
 
598
603
  if (response.ok) {
599
- console.log(`${response.pagination.total} utilisateurs trouvés`);
600
- response.data.forEach((user) => {
601
- console.log(`- ${user.username} (dernière activité: ${user.last_active})`);
602
- });
604
+ console.log(`${response.pagination.total} utilisateurs trouvés`);
605
+ response.data.forEach((user) => {
606
+ console.log(`- ${user.username} (dernière activité: ${user.last_active})`);
607
+ });
603
608
  }
604
609
  ```
605
610
 
@@ -607,26 +612,26 @@ if (response.ok) {
607
612
 
608
613
  ```javascript
609
614
  async function searchAllUsers(query, pageSize = 50) {
610
- let allResults = [];
611
- let offset = 0;
612
- let hasMore = true;
613
-
614
- while (hasMore) {
615
- const response = await client.searchUsers(query, {
616
- limit: pageSize,
617
- offset,
618
- });
619
-
620
- if (!response.ok) break;
621
-
622
- allResults.push(...response.data);
623
- hasMore =
624
- response.pagination.offset + response.pagination.limit <
625
- response.pagination.total;
626
- offset += pageSize;
627
- }
615
+ let allResults = [];
616
+ let offset = 0;
617
+ let hasMore = true;
618
+
619
+ while (hasMore) {
620
+ const response = await client.searchUsers(query, {
621
+ limit: pageSize,
622
+ offset,
623
+ });
624
+
625
+ if (!response.ok) break;
626
+
627
+ allResults.push(...response.data);
628
+ hasMore =
629
+ response.pagination.offset + response.pagination.limit <
630
+ response.pagination.total;
631
+ offset += pageSize;
632
+ }
628
633
 
629
- return allResults;
634
+ return allResults;
630
635
  }
631
636
  ```
632
637
 
@@ -663,7 +668,7 @@ getUser(username: string)
663
668
  const response = await client.getUser("ix-xs");
664
669
 
665
670
  if (!response.ok) {
666
- return console.error(`Utilisateur non trouvé: ${response.error}`);
671
+ return console.error(`Utilisateur non trouvé: ${response.error}`);
667
672
  }
668
673
 
669
674
  const user = response.data;
@@ -682,12 +687,12 @@ Dernière activité: ${new Date(user.last_active).toLocaleDateString("fr-FR")}
682
687
  const response = await client.getUser("jean");
683
688
 
684
689
  if (response.ok) {
685
- const user = response.data;
686
- const daysSinceActive = Math.floor(
687
- (Date.now() - new Date(user.last_active)) / (1000 * 60 * 60 * 24),
688
- );
690
+ const user = response.data;
691
+ const daysSinceActive = Math.floor(
692
+ (Date.now() - new Date(user.last_active)) / (1000 * 60 * 60 * 24),
693
+ );
689
694
 
690
- console.log(`${user.username} a été actif il y a ${daysSinceActive} jours`);
695
+ console.log(`${user.username} a été actif il y a ${daysSinceActive} jours`);
691
696
  }
692
697
  ```
693
698
 
@@ -727,11 +732,11 @@ getUserQuests(username: string)
727
732
  const response = await client.getUserQuests("ix-xs");
728
733
 
729
734
  if (!response.ok) {
730
- return console.error(response.error);
735
+ return console.error(response.error);
731
736
  }
732
737
 
733
738
  response.data.forEach((quest) => {
734
- console.log(`
739
+ console.log(`
735
740
  Personnage: ${quest.character_name}
736
741
  Serveur: ${quest.server.name}
737
742
  Étape: ${quest.current_step}/${quest.quest_template.step_count}
@@ -746,17 +751,17 @@ Recherche: ${quest.wanted_count} / Proposé: ${quest.offered_count}
746
751
  const response = await client.getUserQuests("jean");
747
752
 
748
753
  if (response.ok) {
749
- response.data.forEach((quest) => {
750
- const progression = Math.floor(
751
- (quest.current_step / quest.quest_template.step_count) * 100,
752
- );
754
+ response.data.forEach((quest) => {
755
+ const progression = Math.floor(
756
+ (quest.current_step / quest.quest_template.step_count) * 100,
757
+ );
753
758
 
754
- console.log(`
759
+ console.log(`
755
760
  ${quest.character_name}: ${progression}% complété
756
761
  Étape ${quest.current_step}/${quest.quest_template.step_count}
757
762
  Progression: ${"█".repeat(Math.floor(progression / 5))}${"░".repeat(20 - Math.floor(progression / 5))}
758
763
  `);
759
- });
764
+ });
760
765
  }
761
766
  ```
762
767
 
@@ -766,21 +771,473 @@ Progression: ${"█".repeat(Math.floor(progression / 5))}${"░".repeat(20 - Mat
766
771
  const response = await client.getUserQuests("jean");
767
772
 
768
773
  if (response.ok) {
769
- const providers = response.data.filter((quest) => quest.offered_count > 0);
774
+ const providers = response.data.filter((quest) => quest.offered_count > 0);
775
+
776
+ console.log(
777
+ `${quest.character_name} propose ${quest.offered_count} monstres`,
778
+ );
779
+ }
780
+ ```
781
+
782
+ ---
783
+
784
+ ### Détails d'une quête utilisateur
785
+
786
+ Récupérer les monstres d'une quête spécifique avec filtres et pagination.
787
+
788
+ #### Signature
789
+
790
+ ```javascript
791
+ getUserQuestMonsters(
792
+ username: string,
793
+ quest_slug: string,
794
+ options?: {
795
+ status?: "wanted" | "offered",
796
+ step?: number,
797
+ limit?: number,
798
+ offset?: number
799
+ }
800
+ )
801
+ ```
802
+
803
+ #### Paramètres
804
+
805
+ | Paramètre | Requis | Type | Description |
806
+ | ------------ | ------ | ------ | --------------------------------------------- |
807
+ | `username` | ✅ | string | Nom d'utilisateur |
808
+ | `quest_slug` | ✅ | string | Identifiant (slug) de la quête |
809
+ | `status` | ❌ | string | "wanted" (recherchés) ou "offered" (proposés) |
810
+ | `step` | ❌ | number | Filtrer par numéro d'étape |
811
+ | `limit` | ❌ | number | Nombre de résultats (défaut: 50, max: 200) |
812
+ | `offset` | ❌ | number | Décalage pour pagination (défaut: 0) |
813
+
814
+ #### Types
815
+
816
+ ```javascript
817
+ /**
818
+ * @typedef {Monster & { step: number, owned: number, status: number }} QuestMonster
819
+ * @property {number} step - Numéro d'étape du monstre
820
+ * @property {number} owned - Quantité possédée
821
+ * @property {number} status - Statut (0=neutre, 1=recherché, 2=proposé)
822
+ */
823
+ ```
824
+
825
+ #### Exemples
826
+
827
+ **Lister tous les monstres d'une quête**
828
+
829
+ ```javascript
830
+ const response = await client.getUserQuestMonsters("ix-xs", "abcdef");
831
+
832
+ if (response.ok) {
833
+ console.log(`${response.pagination.total} monstres dans la quête`);
834
+ response.data.forEach((monster) => {
835
+ console.log(
836
+ `${monster.name.fr} - Étape ${monster.step} - Possédé: ${monster.owned}`,
837
+ );
838
+ });
839
+ }
840
+ ```
841
+
842
+ **Filtrer par statut**
843
+
844
+ ```javascript
845
+ // Monstres proposés uniquement
846
+ const response = await client.getUserQuestMonsters("ix-xs", "abcdef", {
847
+ status: "offered",
848
+ });
849
+
850
+ if (response.ok) {
851
+ console.log("Monstres proposés à l'échange:");
852
+ response.data.forEach((m) => console.log(`- ${m.name.fr} (x${m.owned})`));
853
+ }
854
+ ```
855
+
856
+ **Filtrer par étape**
857
+
858
+ ```javascript
859
+ // Monstres de l'étape 5
860
+ const response = await client.getUserQuestMonsters("ix-xs", "abcdef", {
861
+ step: 5,
862
+ });
863
+
864
+ if (response.ok) {
865
+ console.log(`Monstres de l'étape 5: ${response.pagination.total}`);
866
+ }
867
+ ```
868
+
869
+ ---
870
+
871
+ ### Partenaires d'échange
872
+
873
+ Trouve des utilisateurs avec qui échanger des monstres en analysant les compatibilités entre quêtes.
874
+
875
+ #### Signature
876
+
877
+ ```javascript
878
+ matchUserQuest(
879
+ user_api_key: string,
880
+ quest_slug: string,
881
+ options?: {
882
+ direction?: "they_have" | "they_want" | "both",
883
+ active_within_days?: number,
884
+ min_parallel_quests?: number,
885
+ limit?: number,
886
+ offset?: number
887
+ }
888
+ )
889
+ ```
890
+
891
+ #### Paramètres
892
+
893
+ | Paramètre | Requis | Type | Description |
894
+ | --------------------- | ------ | ------ | ------------------------------------------------------- |
895
+ | `user_api_key` | ✅ | string | Clé API de l'utilisateur |
896
+ | `quest_slug` | ✅ | string | Identifiant (slug) de la quête |
897
+ | `direction` | ❌ | string | Type de match (défaut: "both") |
898
+ | `active_within_days` | ❌ | number | Actifs dans les N derniers jours (défaut: 30, max: 365) |
899
+ | `min_parallel_quests` | ❌ | number | Nombre min de quêtes parallèles (défaut: 1, max: 20) |
900
+ | `limit` | ❌ | number | Nombre de résultats (défaut: 20, max: 50) |
901
+ | `offset` | ❌ | number | Décalage pour pagination (défaut: 0) |
902
+
903
+ #### Types
904
+
905
+ ```javascript
906
+ /**
907
+ * @typedef {Monster & { available: number, needed: number, covers_need: boolean }} Wanted
908
+ * @property {number} available - Quantité disponible à l'échange
909
+ * @property {number} needed - Quantité nécessaire
910
+ * @property {boolean} covers_need - Si l'offre couvre entièrement le besoin
911
+ *
912
+ * @typedef {object} Match
913
+ * @property {Search} user - Utilisateur correspondant
914
+ * @property {object} quest - Quête du partenaire
915
+ * @property {string} quest.slug - Identifiant de la quête
916
+ * @property {string} quest.character_name - Nom du personnage
917
+ * @property {number} quest.parallel_quests - Nombre de quêtes parallèles
918
+ * @property {object} matches - Monstres en commun
919
+ * @property {Array<Wanted>} matches.they_have_you_want - Ils ont, vous cherchez
920
+ * @property {Array<Wanted>} matches.you_have_they_want - Vous avez, ils cherchent
921
+ * @property {number} match_score - Score de compatibilité (total de monstres en commun)
922
+ */
923
+ ```
924
+
925
+ #### Exemples
926
+
927
+ **Trouver tous les partenaires**
928
+
929
+ ```javascript
930
+ const response = await client.matchUserQuest("jean_api_key", "abcdef");
931
+
932
+ if (response.ok) {
933
+ console.log(`${response.pagination.total} partenaires trouvés`);
934
+
935
+ response.data.forEach((match) => {
936
+ console.log(`\n${match.user.username} (${match.quest.character_name})`);
937
+ console.log(`Score: ${match.match_score} monstres en commun`);
938
+ console.log(`Ils ont: ${match.matches.they_have_you_want.length}`);
939
+ console.log(`Ils cherchent: ${match.matches.you_have_they_want.length}`);
940
+ });
941
+ }
942
+ ```
943
+
944
+ **Trouver des fournisseurs**
945
+
946
+ ```javascript
947
+ // Utilisateurs proposant des monstres que vous recherchez
948
+ const response = await client.matchUserQuest("jean_api_key", "abcdef", {
949
+ direction: "they_have",
950
+ });
951
+
952
+ if (response.ok) {
953
+ response.data.forEach((match) => {
954
+ console.log(`\n${match.user.username} peut vous fournir:`);
955
+ match.matches.they_have_you_want.forEach((m) => {
956
+ console.log(`- ${m.name.fr} x${m.available} ${m.covers_need ? "✓" : ""}`);
957
+ });
958
+ });
959
+ }
960
+ ```
961
+
962
+ **Filtrer les joueurs actifs**
963
+
964
+ ```javascript
965
+ // Utilisateurs actifs dans les 7 derniers jours avec au moins 3 quêtes parallèles
966
+ const response = await client.matchUserQuest("jean_api_key", "abcdef", {
967
+ active_within_days: 7,
968
+ min_parallel_quests: 3,
969
+ });
970
+
971
+ if (response.ok) {
972
+ console.log(`${response.data.length} joueurs actifs trouvés`);
973
+ }
974
+ ```
975
+
976
+ ---
977
+
978
+ ### Modifier les paramètres d'une quête utilisateur
979
+
980
+ Met à jour la configuration d'une quête (personnage, progression, paramètres d'échange).
981
+
982
+ #### Signature
983
+
984
+ ```javascript
985
+ updateUserQuest(
986
+ user_api_key: string,
987
+ quest_slug: string,
988
+ options: {
989
+ character_name?: string,
990
+ parallel_quests?: number,
991
+ current_step?: number,
992
+ show_trades?: boolean,
993
+ trade_mode?: number,
994
+ trade_offer_threshold?: number | null,
995
+ trade_want_threshold?: number | null,
996
+ never_offer_normal?: boolean,
997
+ never_want_normal?: boolean,
998
+ never_offer_boss?: boolean,
999
+ never_want_boss?: boolean,
1000
+ never_offer_archi?: boolean,
1001
+ never_want_archi?: boolean
1002
+ }
1003
+ )
1004
+ ```
1005
+
1006
+ #### Paramètres
1007
+
1008
+ | Paramètre | Type | Description |
1009
+ | ----------------------- | ------------ | ------------------------------------------------------- |
1010
+ | `character_name` | string | Nom du personnage (max 200 caractères) |
1011
+ | `parallel_quests` | number | Nombre de quêtes en parallèle (1-20) |
1012
+ | `current_step` | number | Étape courante (1-34) |
1013
+ | `show_trades` | boolean | Visibilité de la quête dans la communauté |
1014
+ | `trade_mode` | number | 0 = Automatique, 1 = Mode expert |
1015
+ | `trade_offer_threshold` | number\|null | Seuil minimal pour proposer en mode expert (0-30) |
1016
+ | `trade_want_threshold` | number\|null | Seuil maximal pour rechercher en mode expert (0-30) |
1017
+ | `never_offer_normal` | boolean | Ne jamais proposer les monstres normaux (étapes 1-16) |
1018
+ | `never_want_normal` | boolean | Ne jamais rechercher les monstres normaux (étapes 1-16) |
1019
+ | `never_offer_boss` | boolean | Ne jamais proposer les boss (étapes 17-19) |
1020
+ | `never_want_boss` | boolean | Ne jamais rechercher les boss (étapes 17-19) |
1021
+ | `never_offer_archi` | boolean | Ne jamais proposer les archimonstres (étapes 20+) |
1022
+ | `never_want_archi` | boolean | Ne jamais rechercher les archimonstres (étapes 20+) |
1023
+
1024
+ #### Exemples
1025
+
1026
+ **Mettre à jour les infos de base**
1027
+
1028
+ ```javascript
1029
+ const response = await client.updateUserQuest("jean_api_key", "abcdef", {
1030
+ character_name: "Mon personnage",
1031
+ parallel_quests: 5,
1032
+ current_step: 12,
1033
+ show_trades: true,
1034
+ });
1035
+
1036
+ if (response.ok) {
1037
+ console.log("Quête mise à jour:", response.data);
1038
+ }
1039
+ ```
1040
+
1041
+ **Configurer le mode expert**
1042
+
1043
+ ```javascript
1044
+ const response = await client.updateUserQuest("jean_api_key", "abcdef", {
1045
+ trade_mode: 1,
1046
+ trade_offer_threshold: 6, // Ne proposer que les monstres avec 6+ exemplaires
1047
+ trade_want_threshold: 1, // Rechercher jusqu'à l'étape 1
1048
+ });
1049
+
1050
+ if (response.ok) {
1051
+ console.log("Mode expert configuré");
1052
+ }
1053
+ ```
1054
+
1055
+ **Exclure certains types de monstres**
1056
+
1057
+ ```javascript
1058
+ const response = await client.updateUserQuest("jean_api_key", "abcdef", {
1059
+ never_offer_archi: true, // Ne jamais proposer d'archimonstres
1060
+ never_want_normal: true, // Ne pas rechercher les monstres normaux
1061
+ });
1062
+
1063
+ if (response.ok) {
1064
+ console.log("Filtres appliqués");
1065
+ }
1066
+ ```
1067
+
1068
+ ---
1069
+
1070
+ ### Modifier plusieurs monstres d'une quête utilisateur
1071
+
1072
+ Met à jour les quantités possédées pour plusieurs monstres en une seule requête.
1073
+
1074
+ #### Signature
1075
+
1076
+ ```javascript
1077
+ updateUserQuestMonsters(
1078
+ user_api_key: string,
1079
+ quest_slug: string,
1080
+ monsters: Array<{ monster_name: MonsterName, quantity: number }>
1081
+ )
1082
+ ```
1083
+
1084
+ #### Paramètres
1085
+
1086
+ | Paramètre | Requis | Type | Description |
1087
+ | -------------- | ------ | ------ | --------------------------------------- |
1088
+ | `user_api_key` | ✅ | string | Clé API de l'utilisateur |
1089
+ | `quest_slug` | ✅ | string | Identifiant (slug) de la quête |
1090
+ | `monsters` | ✅ | Array | Liste des monstres à modifier (max 200) |
1091
+
1092
+ #### Contraintes
1093
+
1094
+ - `quantity` : entre 0 et 30
1095
+ - Maximum 200 monstres par requête
1096
+
1097
+ #### Types
1098
+
1099
+ ```javascript
1100
+ /**
1101
+ * @typedef {object} UpdatedMonsters
1102
+ * @property {number} updated_count - Nombre de monstres mis à jour
1103
+ * @property {Array<Monster>} monsters - Monstres mis à jour avec leurs nouvelles valeurs
1104
+ */
1105
+ ```
1106
+
1107
+ #### Exemples
1108
+
1109
+ **Mettre à jour plusieurs monstres**
1110
+
1111
+ ```javascript
1112
+ const response = await client.updateUserQuestMonsters(
1113
+ "jean_api_key",
1114
+ "abcdef",
1115
+ [
1116
+ { monster_name: "Aboub", quantity: 5 },
1117
+ { monster_name: "Bouftou", quantity: 3 },
1118
+ { monster_name: "Tofu", quantity: 10 },
1119
+ ],
1120
+ );
1121
+
1122
+ if (response.ok) {
1123
+ console.log(`${response.data.updated_count} monstres mis à jour`);
1124
+ response.data.monsters.forEach((m) => {
1125
+ console.log(`${m.name.fr}: ${m.quantity} possédés`);
1126
+ });
1127
+ }
1128
+ ```
1129
+
1130
+ **Réinitialiser des quantités**
1131
+
1132
+ ```javascript
1133
+ const response = await client.updateUserQuestMonsters(
1134
+ "jean_api_key",
1135
+ "abcdef",
1136
+ [
1137
+ { monster_name: "Aboub", quantity: 0 },
1138
+ { monster_name: "Bouftou", quantity: 0 },
1139
+ ],
1140
+ );
1141
+
1142
+ if (response.ok) {
1143
+ console.log("Quantités réinitialisées");
1144
+ }
1145
+ ```
1146
+
1147
+ ---
1148
+
1149
+ ### Paramètres de trade manuels d'une quête utilisateur
1150
+
1151
+ Force les quantités proposées/recherchées pour un monstre spécifique, remplaçant le calcul automatique.
1152
+
1153
+ #### Signature
1154
+
1155
+ ```javascript
1156
+ updateUserQuestMonsterTrade(
1157
+ user_api_key: string,
1158
+ quest_slug: string,
1159
+ monster_name: MonsterName,
1160
+ options: {
1161
+ trade_offer?: number | null,
1162
+ trade_want?: number | null
1163
+ }
1164
+ )
1165
+ ```
1166
+
1167
+ #### Paramètres
1168
+
1169
+ | Paramètre | Requis | Type | Description |
1170
+ | -------------- | ------ | ------------ | ---------------------------------------------------------- |
1171
+ | `user_api_key` | ✅ | string | Clé API de l'utilisateur |
1172
+ | `quest_slug` | ✅ | string | Identifiant (slug) de la quête |
1173
+ | `monster_name` | ✅ | MonsterName | Nom du monstre |
1174
+ | `trade_offer` | ❌ | number\|null | Quantité à proposer (0 à owned). null = calcul automatique |
1175
+ | `trade_want` | ❌ | number\|null | Quantité recherchée (0 à 30). null = calcul automatique |
1176
+
1177
+ #### Exemples
1178
+
1179
+ **Forcer les quantités d'échange**
1180
+
1181
+ ```javascript
1182
+ const response = await client.updateUserQuestMonsterTrade(
1183
+ "jean_api_key",
1184
+ "abcdef",
1185
+ "Aboub",
1186
+ {
1187
+ trade_offer: 1, // Proposer 1 Aboub
1188
+ trade_want: 5, // Rechercher 5 Aboub
1189
+ },
1190
+ );
1191
+
1192
+ if (response.ok) {
1193
+ console.log(`${response.data.name.fr}:`);
1194
+ console.log(`- Proposé: ${response.data.trade_offer}`);
1195
+ console.log(`- Recherché: ${response.data.trade_want}`);
1196
+ }
1197
+ ```
770
1198
 
771
- console.log(
772
- `${quest.character_name} propose ${quest.offered_count} monstres`,
773
- );
1199
+ **Réactiver le calcul automatique**
1200
+
1201
+ ```javascript
1202
+ const response = await client.updateUserQuestMonsterTrade(
1203
+ "jean_api_key",
1204
+ "abcdef",
1205
+ "Aboub",
1206
+ {
1207
+ trade_offer: null, // Calcul automatique
1208
+ trade_want: null, // Calcul automatique
1209
+ },
1210
+ );
1211
+
1212
+ if (response.ok) {
1213
+ console.log("Calcul automatique réactivé pour Aboub");
774
1214
  }
775
1215
  ```
776
1216
 
1217
+ **Mode hybride**
1218
+
1219
+ ```javascript
1220
+ // Proposer automatiquement, mais rechercher manuellement
1221
+ const response = await client.updateUserQuestMonsterTrade(
1222
+ "jean_api_key",
1223
+ "abcdef",
1224
+ "Bouftou",
1225
+ {
1226
+ trade_offer: null, // Auto
1227
+ trade_want: 2, // Fixe à 2
1228
+ },
1229
+ );
1230
+ ```
1231
+
1232
+ <br>
1233
+
777
1234
  ## 🔗 Ressources
778
1235
 
779
1236
  - 🌐 [Site Metamob](https://beta.metamob.fr)
780
1237
  - 📖 [Documentation API Officielle](https://beta.metamob.fr/help/api)
781
1238
  - 📦 [Package NPM](https://www.npmjs.com/package/@ix-xs/metamob.api)
782
1239
  - 🔧 [GitHub Repository](https://github.com/ix-xs/metamob.api)
783
- - 💬 [Discord Community](https://discord.gg/SadWCNf2pk)
1240
+ - 💬 [Discord Metamob](https://discord.gg/SadWCNf2pk)
784
1241
 
785
1242
  ## 🐛 Signaler un bug
786
1243
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ix-xs/metamob.api",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "API Metamob Javascript",
5
5
  "keywords": [
6
6
  "API",
package/src/MetamobAPI.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const nodeComfort = require("@ix-xs/node-comfort");
2
- const base = "https://beta.metamob.fr/api/v1";
2
+ const base = "https://metamob.fr/api/v1";
3
3
  const cache = require("./.cache/$");
4
4
 
5
5
  function convertIds(data) {