pokenode-ts 2.3.0 → 2.3.1

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/lib/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["walkPages","#transport","GENDERS"],"sources":["../src/constants/berries.ts","../src/constants/contests.ts","../src/constants/currencies.ts","../src/constants/encounters.ts","../src/constants/endpoints.ts","../src/constants/evolutions.ts","../src/constants/games.ts","../src/constants/items.ts","../src/constants/locations.ts","../src/constants/moves.ts","../src/constants/pokemon.ts","../src/constants/urls.ts","../src/constants/utilities.ts","../src/constants/index.ts","../src/config/cache.ts","../src/config/errors.ts","../src/config/logger.ts","../src/internal/inflight.ts","../src/internal/pool.ts","../src/internal/paginate.ts","../src/internal/retry.ts","../src/internal/url.ts","../src/internal/transport.ts","../src/clients/base.ts","../src/clients/berry.client.ts","../src/clients/contest.client.ts","../src/clients/currency.client.ts","../src/clients/encounter.client.ts","../src/clients/evolution.client.ts","../src/clients/game.client.ts","../src/clients/item.client.ts","../src/clients/location.client.ts","../src/clients/machine.client.ts","../src/clients/move.client.ts","../src/clients/pokemon.client.ts","../src/clients/utility.client.ts","../src/clients/main.client.ts","../src/utils/evolution.ts","../src/utils/localize.ts","../src/utils/resource-id.ts","../src/utils/sprites.ts","../src/utils/type-chart.ts"],"sourcesContent":["/** Enum of Berries (NAME - ID) */\nexport const BERRIES = {\n CHERI: 1,\n CHESTO: 2,\n PECHA: 3,\n RAWST: 4,\n ASPEAR: 5,\n LEPPA: 6,\n ORAN: 7,\n PERSIM: 8,\n LUM: 9,\n SITRUS: 10,\n FIGY: 11,\n WIKI: 12,\n MAGO: 13,\n AGUAV: 14,\n IAPAPA: 15,\n RAZZ: 16,\n BLUK: 17,\n NANAB: 18,\n WEPEAR: 19,\n PINAP: 20,\n POMEG: 21,\n KELPSY: 22,\n QUALOT: 23,\n HONDEW: 24,\n GREPA: 25,\n TAMATO: 26,\n CORNN: 27,\n MAGOST: 28,\n RABUTA: 29,\n NOMEL: 30,\n SPELON: 31,\n PAMTRE: 32,\n WATMEL: 33,\n DURIN: 34,\n BELUE: 35,\n OCCA: 36,\n PASSHO: 37,\n WACAN: 38,\n RINDO: 39,\n YACHE: 40,\n CHOPLE: 41,\n KEBIA: 42,\n SHUCA: 43,\n COBA: 44,\n PAYAPA: 45,\n TANGA: 46,\n CHARTI: 47,\n KASIB: 48,\n HABAN: 49,\n COLBUR: 50,\n BABIRI: 51,\n CHILAN: 52,\n LIECHI: 53,\n GANLON: 54,\n SALAC: 55,\n PETAYA: 56,\n APICOT: 57,\n LANSAT: 58,\n STARF: 59,\n ENIGMA: 60,\n MICLE: 61,\n CUSTAP: 62,\n JABOCA: 63,\n ROWAP: 64,\n KEE: 65,\n MARANGA: 66,\n HOPO: 67,\n ROSELI: 68,\n} as const;\n\n/** Enum of Berry Firmnesses (NAME - ID) */\nexport const BERRY_FIRMNESSES = {\n VERY_SOFT: 1,\n SOFT: 2,\n HARD: 3,\n VERY_HARD: 4,\n SUPER_HARD: 5,\n} as const;\n\nexport const BERRY_FLAVORS = {\n SPICY: 1,\n DRY: 2,\n SWEET: 3,\n BITTER: 4,\n SOUR: 5,\n} as const;\n","export const CONTEST_TYPES = {\n COOL: 1,\n BEAUTY: 2,\n CUTE: 3,\n SMART: 4,\n TOUGH: 5,\n} as const;\n","export const CURRENCIES = {\n POKE_DOLLAR: 1,\n COIN: 2,\n VOLCANIC_ASH: 3,\n POKE_COUPON: 4,\n BERRY_POWDER: 5,\n BATTLE_POINT: 6,\n SPHERE: 7,\n CASTLE_POINT: 8,\n WATT: 9,\n ATHLETE_POINT: 10,\n DREAM_POINT: 11,\n DREAM_WORLD_BERRY: 12,\n POKE_MILE: 13,\n FESTIVAL_COIN: 14,\n POKE_BEAN: 15,\n HOME_POINT: 16,\n MERIT_POINT: 17,\n LEAGUE_POINT: 18,\n BLUEBERRY_POINT: 19,\n} as const;\n","export const ENCOUNTER_METHODS = {\n WALK: 1,\n OLD_ROD: 2,\n GOOD_ROD: 3,\n SUPER_ROD: 4,\n SURF: 5,\n ROCK_SMASH: 6,\n HEADBUTT: 7,\n DARK_GRASS: 8,\n GRASS_SPOTS: 9,\n CAVE_SPOTS: 10,\n BRIDGE_SPOTS: 11,\n SUPER_ROD_SPOTS: 12,\n SURF_SPOTS: 13,\n YELLOW_FLOWERS: 14,\n PURPLE_FLOWERS: 15,\n RED_FLOWERS: 16,\n ROUGH_TERRAIN: 17,\n GIFT: 18,\n GIFT_EGG: 19,\n STATIC: 20,\n POKEFLUTE: 21,\n HEADBUTT_LOW: 22,\n HEADBUTT_NORMAL: 23,\n HEADBUTT_HIGH: 24,\n SQUIRT_BOTTLE: 25,\n WAILMER_PAIL: 26,\n SEAWEED: 27,\n ROAMING_GRASS: 28,\n ROAMING_WATER: 29,\n DEVON_SCOPE: 30,\n FEEBAS_TILE_FISHING: 31,\n ISLAND_SCAN: 32,\n SOS: 33,\n BUBBLING_SPOTS: 34,\n BERRY_TREES: 35,\n NPC_TRADE: 36,\n SOS_FROM_BUBBLING_SPOT: 37,\n OVERWORLD: 38,\n OVERWORLD_WATER: 39,\n OVERWORLD_FLYING: 40,\n OVERWORLD_SPECIAL: 41,\n OVERWORLD_FLYING_SPECIAL: 42,\n OVERWORLD_WATER_SPECIAL: 43,\n HORDE: 44,\n COLOSSEUM_BONUS_DISC_US: 45,\n COLOSSEUM_BONUS_DISC_JPN: 46,\n POKEMON_CHANNEL_PAL: 47,\n POKEMON_RANGER: 48,\n POKEMON_BATTLE_REVOLUTION: 49,\n NEW_YORK_POKECENTER_WISH_EGGS: 50,\n SNAG: 51,\n SNAG_REMATCH: 52,\n POKESPOT: 53,\n HIDDEN_GROTTO: 54,\n HONEY_TREE: 55,\n OVERWORLD_DIRT: 56,\n WANDERER: 57,\n WANDERER_WATER: 58,\n CHASE_WATER: 59,\n DYNAMAX_ADVENTURE: 60,\n MAX_RAID: 61,\n TRASH_CAN_AMBUSH: 62,\n RUSTLING_BUSH_AMBUSH: 63,\n CEILING_AMBUSH: 64,\n GROUND_AMBUSH: 65,\n SKY_AMBUSH: 66,\n /**\n * @deprecated Misspelled: the endpoint names this `headbutt-high`.\n * Use {@link ENCOUNTER_METHODS.HEADBUTT_HIGH}. Removed in 3.0.\n */\n HEADBUT_HIGH: 24,\n /**\n * @deprecated The endpoint names this `static` now.\n * Use {@link ENCOUNTER_METHODS.STATIC}. Removed in 3.0.\n */\n ONLY_ONE: 20,\n} as const;\n\nexport const ENCOUNTER_CONDITIONS = {\n SWARM: 1,\n TIME: 2,\n RADAR: 3,\n SLOT2: 4,\n RADIO: 5,\n SEASON: 6,\n STARTER: 7,\n TV_OPTION: 8,\n STORY_PROGRESS: 9,\n OTHER: 10,\n ITEM: 11,\n WEEKDAY: 12,\n FIRST_PARTY_POKEMON: 13,\n SPECIAL_ENCOUNTER: 14,\n TRADE: 15,\n COINS: 16,\n FRIEND_SAFARI_SLOT: 17,\n GREAT_MARSH_DAILY_SLOT: 18,\n HONEY_TREE_GROUP: 19,\n HEADBUTT_TREE: 20,\n BACKLOT: 21,\n BUG_CATCHING_CONTEST: 22,\n SAVE_DATA: 23,\n ALOLAN_DIGLETT_FOUND: 24,\n WEATHER: 25,\n JOHTO_SAFARI_BLOCKS: 26,\n MAX_DEN_RARITY: 27,\n MAX_DEN_RATING: 28,\n BERRY_TREE_TYPE: 29,\n TRASH_CAN_TYPE: 30,\n} as const;\n\nexport const ENCOUNTER_CONDITION_VALUES = {\n SWARM_YES: 1,\n SWARM_NO: 2,\n TIME_MORNING: 3,\n TIME_DAY: 4,\n TIME_NIGHT: 5,\n RADAR_ON: 6,\n RADAR_OFF: 7,\n SLOT2_NONE: 8,\n SLOT2_RUBY: 9,\n SLOT2_SAPPHIRE: 10,\n SLOT2_EMERALD: 11,\n SLOT2_FIRERED: 12,\n SLOT2_LEAFGREEN: 13,\n RADIO_OFF: 14,\n RADIO_HOENN: 15,\n RADIO_SINNOH: 16,\n SEASON_SPRING: 17,\n SEASON_SUMMER: 18,\n SEASON_AUTUMN: 19,\n SEASON_WINTER: 20,\n STARTER_BULBASAUR: 21,\n STARTER_SQUIRTLE: 22,\n STARTER_CHARMANDER: 23,\n STARTER_CHESPIN: 24,\n STARTER_FENNEKIN: 25,\n STARTER_FROAKIE: 26,\n TV_OPTION_BLUE: 27,\n TV_OPTION_RED: 28,\n STORY_PROGRESS_AWAKENED_BEASTS: 29,\n STORY_PROGRESS_BEAT_GALACTIC_CORONET: 30,\n STORY_PROGRESS_OAK_ETERNA_CITY: 31,\n STORY_PROGRESS_VERMILION_COPYCAT: 32,\n STORY_PROGRESS_MET_TORNADUS_THUNDURUS: 33,\n STORY_PROGRESS_BEAT_ELITE_FOUR_ROUND_TWO: 34,\n STORY_PROGRESS_HALL_OF_FAME: 35,\n STORY_PROGRESS_NONE: 36,\n STORY_PROGRESS_NATIONAL_DEX: 37,\n OTHER_NONE: 38,\n OTHER_SNORLAX_11_BEAT_LEAGUE: 39,\n OTHER_VIRTUAL_CONSOLE: 40,\n STORY_PROGRESS_CURE_ELDRITCH_NIGHTMARES: 41,\n OTHER_TALK_TO_CYNTHIAS_GRANDMOTHER: 42,\n ITEM_NONE: 43,\n ITEM_ADAMANT_ORB: 44,\n ITEM_LUSTROUS_ORB: 45,\n ITEM_HELIX_FOSSIL: 46,\n ITEM_DOME_FOSSIL: 47,\n ITEM_OLD_AMBER: 48,\n ITEM_ROOT_FOSSIL: 49,\n ITEM_CLAW_FOSSIL: 50,\n STORY_PROGRESS_DEFEAT_JUPITER: 51,\n STORY_PROGRESS_BEAT_TEAM_GALACTIC_IRON_ISLAND: 52,\n OTHER_CORRECT_PASSWORD: 53,\n STORY_PROGRESS_ZEPHYR_BADGE: 54,\n STORY_PROGRESS_BEAT_RED: 55,\n OTHER_RECEIVED_KANTO_STARTER: 56,\n STORY_PROGRESS_RECEIVE_TM_FROM_CLAIRE: 57,\n OTHER_REGIROCK_REGICE_REGISTEEL_IN_PARTY: 58,\n WEEKDAY_SUNDAY: 59,\n WEEKDAY_MONDAY: 60,\n WEEKDAY_TUESDAY: 61,\n WEEKDAY_WEDNESDAY: 62,\n WEEKDAY_THURSDAY: 63,\n WEEKDAY_FRIDAY: 64,\n WEEKDAY_SATURDAY: 65,\n FIRST_PARTY_POKEMON_HIGH_FRIENDSHIP: 66,\n STORY_PROGRESS_DEFEAT_MARS: 67,\n ITEM_ODD_KEYSTONE: 68,\n OTHER_TALKED_TO_32_PEOPLE_UNDERGROUND: 69,\n STORY_PROGRESS_RETURNED_MACHINE_PART: 70,\n OTHER_EVENT_ARCEUS_IN_PARTY: 71,\n SPECIAL_ENCOUNTER_COULDNT_CAPTURE_BEFORE: 72,\n ITEM_ICE_KEY: 73,\n ITEM_IRON_KEY: 74,\n STORY_PROGRESS_JUNIPER_CAVE_OF_BEING: 75,\n ITEM_LUNAR_WING: 76,\n STORY_PROGRESS_QUAKE_BADGE: 77,\n ITEM_LIGHT_STONE: 78,\n ITEM_DARK_STONE: 79,\n OTHER_CAPTURED_RESHIRAM_OR_ZEKROM: 80,\n DEFEATED_GHETSIS: 81,\n OTHER_FOUND_11_TIMES_ROAMING: 82,\n TIME_MINUTE_00_TO_19: 83,\n TIME_MINUTE_20_TO_39: 84,\n TIME_MINUTE_40_TO_59: 85,\n TIME_04_00_TO_19_59: 86,\n TIME_20_00_TO_21_59: 87,\n TIME_21_00_TO_03_59: 88,\n ITEM_TIDAL_BELL: 89,\n ITEM_CLEAR_BELL: 90,\n STORY_PROGRESS_DEFEATED_GROUDON_OR_KYOGRE: 91,\n OTHER_UXIE_MESPRIT_AZELF_IN_PARTY: 92,\n OTHER_NICKNAMED_COLD_ITEM_REGICE_REGIROCK_REGISTEEL3: 93,\n OTHER_DIALGA_OR_PALKIA_IN_PARTY: 94,\n OTHER_CASTFORM_IN_PARTY: 95,\n OTHER_LEVEL_100_POKEMON_IN_PARTY: 96,\n OTHER_TORNADUS_THUNDURUS_IN_PARTY: 97,\n OTHER_RESHIRAM_ZEKROM_IN_PARTY: 98,\n OTHER_CAPTURED_ALL_ULTRA_BEASTS: 99,\n STORY_PROGRESS_FINISHED_LOOKER_SIDEQUEST: 100,\n STORY_PROGRESS_BEAT_OLIVIAS_TRIAL: 101,\n OTHER_RAIKOU_ENTEI_IN_PARTY: 102,\n OTHER_GROUDON_KYOGRE_IN_PARTY: 103,\n OTHER_DIALGA_PALKIA_IN_PARTY: 104,\n OTHER_SCAN_QR_CODE: 105,\n OTHER_CAUGHT_ARTICUNO: 106,\n OTHER_CAUGHT_ZAPDOS: 107,\n OTHER_CAUGHT_MOLTRES: 108,\n TRADE_TOGEPI_OR_TOGETIC: 109,\n TRADE_TRAPINCH: 110,\n TRADE_SURSKIT: 111,\n TRADE_WOOPER: 112,\n STORY_PROGRESS_CATCH_ALL_SHADOW_POKEMON: 113,\n OTHER_COMPLETE_MT_BATTLE: 114,\n COINS_180: 115,\n COINS_500: 116,\n COINS_1200: 117,\n COINS_2800: 118,\n COINS_5500: 119,\n COINS_9999: 120,\n COINS_120: 121,\n COINS_750: 122,\n COINS_2500: 123,\n COINS_4600: 124,\n COINS_6500: 125,\n COINS_230: 126,\n COINS_1000: 127,\n COINS_2680: 128,\n COINS_3333: 129,\n COINS_6666: 130,\n COINS_200: 131,\n COINS_700: 132,\n COINS_2100: 133,\n COINS_100: 134,\n COINS_800: 135,\n COINS_1500: 136,\n COINS_2222: 137,\n COINS_5555: 138,\n COINS_8888: 139,\n COINS_150: 140,\n COINS_620: 141,\n COINS_2880: 142,\n COINS_5400: 143,\n COINS_8300: 144,\n TRADE_ABRA: 145,\n TRADE_NIDORAN_M: 146,\n TRADE_NIDORINO: 147,\n TRADE_SLOWBRO: 148,\n TRADE_POLIWHIRL: 149,\n TRADE_SPEAROW: 150,\n TRADE_RAICHU: 151,\n TRADE_VENONAT: 152,\n TRADE_PONYTA: 153,\n TRADE_CLEFAIRY: 154,\n TRADE_CUBONE: 155,\n TRADE_LICKITUNG: 156,\n TRADE_TANGELA: 157,\n TRADE_GOLDUCK: 158,\n TRADE_GROWLITHE: 159,\n TRADE_KANGASKHAN: 160,\n TRADE_BELLSPROUT: 161,\n TRADE_DROWZEE: 162,\n TRADE_KRABBY: 163,\n TRADE_DRAGONAIR: 164,\n TRADE_CHANSEY: 165,\n TRADE_GLOOM: 166,\n TRADE_HAUNTER: 167,\n TRADE_DUGTRIO: 168,\n TRADE_SLAKOTH: 169,\n TRADE_PIKACHU: 170,\n TRADE_BELLOSSOM: 171,\n TRADE_RALTS: 172,\n TRADE_VOLBEAT: 173,\n TRADE_BAGON: 174,\n TRADE_SKITTY: 175,\n FRIEND_SAFARI_SLOT_1: 176,\n FRIEND_SAFARI_SLOT_2: 177,\n FRIEND_SAFARI_SLOT_3: 178,\n ITEM_SKULL_FOSSIL: 179,\n ITEM_ARMOR_FOSSIL: 180,\n GREAT_MARSH_DAILY_SLOT_NONE: 181,\n GREAT_MARSH_DAILY_SLOT_1_OF_32: 182,\n GREAT_MARSH_DAILY_SLOT_2_OF_32: 183,\n GREAT_MARSH_DAILY_SLOT_3_OF_32: 184,\n GREAT_MARSH_DAILY_SLOT_5_OF_32: 185,\n STORY_PROGRESS_BEFORE_NATIONAL_DEX: 186,\n GREAT_MARSH_DAILY_SLOT_4_OF_32: 187,\n GREAT_MARSH_DAILY_SLOT_15_OF_32: 188,\n HONEY_TREE_GROUP_A: 189,\n HONEY_TREE_GROUP_B: 190,\n HONEY_TREE_GROUP_C: 191,\n HEADBUTT_TREE_COMMON: 192,\n HEADBUTT_TREE_RARE: 193,\n HEADBUTT_TREE_SECRET: 194,\n TRADE_COTTONEE: 195,\n TRADE_PETILIL: 196,\n TRADE_EMOLGA: 197,\n TRADE_MANTINE: 198,\n TRADE_DITTO: 199,\n TRADE_EXCADRILL: 200,\n TRADE_HIPPOWDON: 201,\n BACKLOT_NOT_MENTIONED: 202,\n BACKLOT_MENTIONED: 203,\n BUG_CATCHING_CONTEST_NO: 204,\n BUG_CATCHING_CONTEST_YES: 205,\n SAVE_DATA_FROM_LETS_GO_PIKACHU: 206,\n SAVE_DATA_FROM_LETS_GO_EEVEE: 207,\n ITEM_FOSSILIZED_BIRD: 208,\n ITEM_FOSSILIZED_DRAKE: 209,\n ITEM_FOSSILIZED_DINO: 210,\n ITEM_FOSSILIZED_FISH: 211,\n STORY_PROGRESS_MASTER_DOJO_COMPLETE_FIRST_TRIAL: 212,\n STORY_PROGRESS_MASTER_DOJO_COMPLETE_THIRD_TRIAL: 213,\n ALOLAN_DIGLETT_FOUND_5: 214,\n ALOLAN_DIGLETT_FOUND_10: 215,\n ALOLAN_DIGLETT_FOUND_20: 216,\n ALOLAN_DIGLETT_FOUND_30: 217,\n ALOLAN_DIGLETT_FOUND_40: 218,\n ALOLAN_DIGLETT_FOUND_50: 219,\n ALOLAN_DIGLETT_FOUND_75: 220,\n ALOLAN_DIGLETT_FOUND_100: 221,\n ALOLAN_DIGLETT_FOUND_150: 222,\n STARTER_GROOKEY: 223,\n STARTER_SCORBUNNY: 224,\n STARTER_SOBBLE: 225,\n STORY_PROGRESS_SAVE_VILLAGE_FROM_GLASTRIER_SPECTRIER: 226,\n STORY_PROGRESS_CATCH_FIVE_ULTRA_BEASTS: 227,\n TRADE_BUNNELBY: 228,\n TRADE_MEOWTH_GALAR: 229,\n TRADE_MINCCINO: 230,\n TRADE_TOXEL: 231,\n TRADE_MARACTUS: 232,\n TRADE_YAMASK_GALAR: 233,\n TRADE_VANILLISH: 234,\n TRADE_OBSTAGOON: 235,\n TRADE_FROSMOTH: 236,\n TRADE_FARFETCHD_GALAR: 237,\n TRADE_CORSOLA_GALAR: 238,\n TRADE_PONYTA_GALAR: 239,\n TRADE_MR_MIME_GALAR: 240,\n TRADE_DARUMAKA_GALAR: 241,\n TRADE_ZIGZAGOON_GALAR: 242,\n TRADE_STUNFISK_GALAR: 243,\n TRADE_WEEZING_GALAR: 244,\n TRADE_EXEGGUTOR: 245,\n TRADE_MAROWAK: 246,\n WEATHER_NORMAL: 247,\n WEATHER_OVERCAST: 248,\n WEATHER_RAINING: 249,\n WEATHER_THUNDERSTORM: 250,\n WEATHER_SNOWING: 251,\n WEATHER_SNOWSTORM: 252,\n WEATHER_SANDSTORM: 253,\n WEATHER_INTENSE_SUN: 254,\n WEATHER_FOG: 255,\n STORY_PROGRESS_BEFORE_HALL_OF_FAME: 256,\n JOHTO_SAFARI_BLOCKS_INACTIVE: 257,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_2: 258,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_3: 259,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_4: 260,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_5: 261,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_6: 262,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_10: 263,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_12: 264,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_14: 265,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_15: 266,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_24: 267,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_28: 268,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_35: 269,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_49: 270,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_3: 271,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_4: 272,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_5: 273,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_8: 274,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_10: 275,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_14: 276,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_15: 277,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_18: 278,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_20: 279,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_28: 280,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_35: 281,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_42: 282,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_49: 283,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_56: 284,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_3: 285,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_4: 286,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_5: 287,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_6: 288,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_8: 289,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_10: 290,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_15: 291,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_21: 292,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_24: 293,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_28: 294,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_35: 295,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_42: 296,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_49: 297,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_56: 298,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_63: 299,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_2: 300,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_3: 301,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_4: 302,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_5: 303,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_6: 304,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_7: 305,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_8: 306,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_9: 307,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_10: 308,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_12: 309,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_13: 310,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_14: 311,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_15: 312,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_16: 313,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_18: 314,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_20: 315,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_24: 316,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_28: 317,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_35: 318,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_42: 319,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_49: 320,\n ITEM_COVER_FOSSIL: 321,\n ITEM_PLUME_FOSSIL: 322,\n OTHER_GIRATINA_NOT_CAUGHT_IN_DISTORTION_WORLD: 323,\n OTHER_FIND_50_CAVERN_FOOTPRINTS: 324,\n OTHER_FIND_50_GRASSLAND_FOOTPRINTS: 325,\n OTHER_FIND_50_IRON_WILL_FOOTPRINTS: 326,\n OTHER_REGIROCK_REGICE_REGISTEEL_REGIELEKI_REGIDRAGO_IN_PARTY: 327,\n OTHER_CHOOSE_REGIELEKI_PATTERN: 328,\n OTHER_CHOOSE_REGIDRAGO_PATTERN: 329,\n OTHER_GROW_ICEROOT_CARROT: 330,\n OTHER_GROW_SHADEROOT_CARROT: 331,\n OTHER_TALKED_TO_32_PEOPLE: 332,\n OTHER_EAT_CURRY_WITH_COBALION_TERRAKION_VIRIZION: 333,\n ITEM_REINS_OF_UNITY: 334,\n OTHER_WITNESS_GALARIAN_BIRD_FIGHT: 335,\n MAX_DEN_RARITY_COMMON: 336,\n MAX_DEN_RARITY_RARE: 337,\n MAX_DEN_RATING_1_STAR: 338,\n MAX_DEN_RATING_2_STAR: 339,\n MAX_DEN_RATING_3_STAR: 340,\n MAX_DEN_RATING_4_STAR: 341,\n MAX_DEN_RATING_5_STAR: 342,\n MAX_DEN_RARITY_SPECIAL: 343,\n BERRY_TREE_TYPE_RED: 344,\n BERRY_TREE_TYPE_BLUE: 345,\n BERRY_TREE_TYPE_PURPLE: 346,\n BERRY_TREE_TYPE_GREEN: 347,\n BERRY_TREE_TYPE_YELLOW: 348,\n BERRY_TREE_TYPE_PINK: 349,\n TRASH_CAN_TYPE_DAILY: 350,\n TRASH_CAN_TYPE_TUESDAY: 351,\n TRASH_CAN_TYPE_THURSDAY: 352,\n TRADE_NIDORAN_F: 353,\n TRADE_NIDORINA: 354,\n TRADE_MACHOP: 355,\n TRADE_BUIZEL: 356,\n TRADE_MEDICHAM: 357,\n TRADE_FINNEON: 358,\n TRADE_FORRETRESS: 359,\n TRADE_BONSLY: 360,\n TRADE_ANY_POKEMON: 361,\n /**\n * @deprecated Misspelled: the endpoint names this `other-snorlax-11-beat-league`.\n * Use {@link ENCOUNTER_CONDITION_VALUES.OTHER_SNORLAX_11_BEAT_LEAGUE}. Removed in 3.0.\n */\n OTHER_SNORLAX_LL_BEAT_LEAGUE: 39,\n /**\n * @deprecated Misspelled: the endpoint names this `radio-hoenn`.\n * Use {@link ENCOUNTER_CONDITION_VALUES.RADIO_HOENN}. Removed in 3.0.\n */\n RADIO_HOEN: 15,\n /**\n * @deprecated Misspelled: the endpoint names this `slot2-sapphire`.\n * Use {@link ENCOUNTER_CONDITION_VALUES.SLOT2_SAPPHIRE}. Removed in 3.0.\n */\n SLOT2_SAPHIRE: 10,\n /**\n * @deprecated The endpoint names this `story-progress-vermilion-copycat` now.\n * Use {@link ENCOUNTER_CONDITION_VALUES.STORY_PROGRESS_VERMILION_COPYCAT}. Removed in 3.0.\n */\n STORY_PROGRESS_OAK_VERMILION_COPYCAT: 32,\n /**\n * @deprecated Misspelled: the endpoint names this `season-autumn`.\n * Use {@link ENCOUNTER_CONDITION_VALUES.SEASON_AUTUMN}. Removed in 3.0.\n */\n SWASON_AUTUMN: 19,\n} as const;\n","/**\n * Endpoints of the PokéAPI\n */\nexport const ENDPOINTS = {\n BERRY: \"/berry\",\n BERRY_FIRMNESS: \"/berry-firmness\",\n BERRY_FLAVOR: \"/berry-flavor\",\n CONTEST_TYPE: \"/contest-type\",\n CONTEST_EFFECT: \"/contest-effect\",\n SUPER_CONTEST_EFFECT: \"/super-contest-effect\",\n CURRENCY: \"/currency\",\n ENCOUNTER_METHOD: \"/encounter-method\",\n ENCOUNTER_CONDITION: \"/encounter-condition\",\n ENCOUNTER_CONDITION_VALUE: \"/encounter-condition-value\",\n EVOLUTION_CHAIN: \"/evolution-chain\",\n EVOLUTION_TRIGGER: \"/evolution-trigger\",\n GENERATION: \"/generation\",\n POKEDEX: \"/pokedex\",\n VERSION: \"/version\",\n VERSION_GROUP: \"/version-group\",\n ITEM: \"/item\",\n ITEM_ATTRIBUTE: \"/item-attribute\",\n ITEM_CATEGORY: \"/item-category\",\n ITEM_FLING_EFFECT: \"/item-fling-effect\",\n ITEM_POCKET: \"/item-pocket\",\n LOCATION: \"/location\",\n LOCATION_AREA: \"/location-area\",\n PALPARK_AREA: \"/pal-park-area\",\n REGION: \"/region\",\n MACHINE: \"/machine\",\n MOVE: \"/move\",\n MOVE_AILMENT: \"/move-ailment\",\n MOVE_BATTLE_STYLE: \"/move-battle-style\",\n MOVE_CATEGORY: \"/move-category\",\n MOVE_DAMAGE_CLASS: \"/move-damage-class\",\n MOVE_LEARN_METHOD: \"/move-learn-method\",\n MOVE_TARGET: \"/move-target\",\n ABILITY: \"/ability\",\n CHARACTERISTIC: \"/characteristic\",\n EGG_GROUP: \"/egg-group\",\n GENDER: \"/gender\",\n GROWTH_RATE: \"/growth-rate\",\n NATURE: \"/nature\",\n POKEATHLON_STAT: \"/pokeathlon-stat\",\n POKEMON: \"/pokemon\",\n POKEMON_COLOR: \"/pokemon-color\",\n POKEMON_FORM: \"/pokemon-form\",\n POKEMON_HABITAT: \"/pokemon-habitat\",\n POKEMON_SHAPE: \"/pokemon-shape\",\n POKEMON_SPECIES: \"/pokemon-species\",\n STAT: \"/stat\",\n TYPE: \"/type\",\n LANGUAGE: \"/language\",\n} as const;\n\ntype ObjectValue<T> = T[keyof T];\nexport type Endpoint = ObjectValue<typeof ENDPOINTS>;\n","export const EVOLUTION_TRIGGERS = {\n LEVEL_UP: 1,\n TRADE: 2,\n USE_ITEM: 3,\n SHED: 4,\n SPIN: 5,\n TOWER_OF_DARKNESS: 6,\n TOWER_OF_WATERS: 7,\n THREE_CRITICAL_HITS: 8,\n TAKE_DAMAGE: 9,\n OTHER: 10,\n AGILE_STYLE_MOVE: 11,\n STRONG_STYLE_MOVE: 12,\n RECOIL_DAMAGE: 13,\n USE_MOVE: 14,\n THREE_DEFEATED_BISHARP: 15,\n GIMMIGHOUL_COINS: 16,\n /**\n * @deprecated Misspelled: the endpoint names this trigger `tower-of-waters`.\n * Use {@link EVOLUTION_TRIGGERS.TOWER_OF_WATERS}. Removed in 3.0.\n */\n TOWER_OF_WATER: 7,\n} as const;\n","export const GENERATIONS = {\n GENERATION_I: 1,\n GENERATION_II: 2,\n GENERATION_III: 3,\n GENERATION_IV: 4,\n GENERATION_V: 5,\n GENERATION_VI: 6,\n GENERATION_VII: 7,\n GENERATION_VIII: 8,\n GENERATION_IX: 9,\n} as const;\n\n/**\n * ## Generation Name\n * A generation as the PokéAPI names it, which is what a\n * `NamedAPIResource<Generation>` carries and what the helpers that resolve a\n * resource's past state are given.\n *\n * Written out rather than derived from {@link GENERATIONS}: turning\n * `GENERATION_VIII` into `generation-viii` in the type system takes a recursive\n * template literal, and the set is closed and nine long.\n */\nexport type GenerationName =\n | \"generation-i\"\n | \"generation-ii\"\n | \"generation-iii\"\n | \"generation-iv\"\n | \"generation-v\"\n | \"generation-vi\"\n | \"generation-vii\"\n | \"generation-viii\"\n | \"generation-ix\";\n\nexport const POKEDEXES = {\n NATIONAL: 1,\n KANTO: 2,\n ORIGINAL_JOHTO: 3,\n HOENN: 4,\n ORIGINAL_SINNOH: 5,\n EXTENDED_SINNOH: 6,\n UPDATED_JOHTO: 7,\n ORIGINAL_UNOVA: 8,\n UPDATED_UNOVA: 9,\n CONQUEST_GALLERY: 11,\n KALOS_CENTRAL: 12,\n KALOS_COASTAL: 13,\n KALOS_MOUNTAIN: 14,\n UPDATED_HOENN: 15,\n ORIGINAL_ALOLA: 16,\n ORIGINAL_MELEMELE: 17,\n ORIGINAL_AKALA: 18,\n ORIGINAL_ULAULA: 19,\n ORIGINAL_PONI: 20,\n UPDATED_ALOLA: 21,\n UPDATED_MELEMELE: 22,\n UPDATED_AKALA: 23,\n UPDATED_ULAULA: 24,\n UPDATED_PONI: 25,\n LETSGO_KANTO: 26,\n GALAR: 27,\n ISLE_OF_ARMOR: 28,\n CROWN_TUNDRA: 29,\n HISUI: 30,\n PALDEA: 31,\n KITAKAMI: 32,\n BLUEBERRY: 33,\n LUMIOSE_CITY: 34,\n HYPERSPACE: 35,\n CHAMPIONS: 36,\n /**\n * @deprecated Misspelled: the endpoint names this `kalos-mountain`.\n * Use {@link POKEDEXES.KALOS_MOUNTAIN}. Removed in 3.0.\n */\n KALOS_MONTAIN: 14,\n /**\n * @deprecated The endpoint names this `letsgo-kanto` now.\n * Use {@link POKEDEXES.LETSGO_KANTO}. Removed in 3.0.\n */\n UPDATED_KANTO: 26,\n} as const;\n\nexport const VERSIONS = {\n RED: 1,\n BLUE: 2,\n YELLOW: 3,\n GOLD: 4,\n SILVER: 5,\n CRYSTAL: 6,\n RUBY: 7,\n SAPPHIRE: 8,\n EMERALD: 9,\n FIRERED: 10,\n LEAFGREEN: 11,\n DIAMOND: 12,\n PEARL: 13,\n PLATINUM: 14,\n HEARTGOLD: 15,\n SOULSILVER: 16,\n BLACK: 17,\n WHITE: 18,\n COLOSSEUM: 19,\n XD: 20,\n BLACK_2: 21,\n WHITE_2: 22,\n X: 23,\n Y: 24,\n OMEGA_RUBY: 25,\n ALPHA_SAPPHIRE: 26,\n SUN: 27,\n MOON: 28,\n ULTRA_SUN: 29,\n ULTRA_MOON: 30,\n LETS_GO_PIKACHU: 31,\n LETS_GO_EEVEE: 32,\n SWORD: 33,\n SHIELD: 34,\n THE_ISLE_OF_ARMOR_SWORD: 35,\n THE_CROWN_TUNDRA_SWORD: 36,\n BRILLIANT_DIAMOND: 37,\n SHINING_PEARL: 38,\n LEGENDS_ARCEUS: 39,\n SCARLET: 40,\n VIOLET: 41,\n THE_TEAL_MASK_SCARLET: 42,\n THE_INDIGO_DISK_SCARLET: 43,\n RED_JAPAN: 44,\n GREEN_JAPAN: 45,\n BLUE_JAPAN: 46,\n LEGENDS_ZA: 47,\n MEGA_DIMENSION: 48,\n CHAMPIONS: 49,\n THE_ISLE_OF_ARMOR_SHIELD: 50,\n THE_CROWN_TUNDRA_SHIELD: 51,\n THE_TEAL_MASK_VIOLET: 52,\n THE_INDIGO_DISK_VIOLET: 53,\n /**\n * @deprecated The endpoint names this `the-crown-tundra-sword` now.\n * Use {@link VERSIONS.THE_CROWN_TUNDRA_SWORD}. Removed in 3.0.\n */\n THE_CROWN_TUNDRA: 36,\n /**\n * @deprecated The endpoint names this `the-isle-of-armor-sword` now.\n * Use {@link VERSIONS.THE_ISLE_OF_ARMOR_SWORD}. Removed in 3.0.\n */\n THE_ISLE_OF_ARMOR: 35,\n} as const;\n\nexport const VERSION_GROUPS = {\n RED_BLUE: 1,\n YELLOW: 2,\n GOLD_SILVER: 3,\n CRYSTAL: 4,\n RUBY_SAPPHIRE: 5,\n EMERALD: 6,\n FIRERED_LEAFGREEN: 7,\n DIAMOND_PEARL: 8,\n PLATINUM: 9,\n HEARTGOLD_SOULSILVER: 10,\n BLACK_WHITE: 11,\n COLOSSEUM: 12,\n XD: 13,\n BLACK_2_WHITE_2: 14,\n X_Y: 15,\n OMEGA_RUBY_ALPHA_SAPPHIRE: 16,\n SUN_MOON: 17,\n ULTRA_SUN_ULTRA_MOON: 18,\n LETS_GO_PIKACHU_LETS_GO_EEVEE: 19,\n SWORD_SHIELD: 20,\n THE_ISLE_OF_ARMOR: 21,\n THE_CROWN_TUNDRA: 22,\n BRILLIANT_DIAMOND_SHINING_PEARL: 23,\n LEGENDS_ARCEUS: 24,\n SCARLET_VIOLET: 25,\n THE_TEAL_MASK: 26,\n THE_INDIGO_DISK: 27,\n RED_GREEN_JAPAN: 28,\n BLUE_JAPAN: 29,\n LEGENDS_ZA: 30,\n MEGA_DIMENSION: 31,\n CHAMPIONS: 32,\n /**\n * @deprecated The endpoint names this `brilliant-diamond-shining-pearl` now.\n * Use {@link VERSION_GROUPS.BRILLIANT_DIAMOND_SHINING_PEARL}. Removed in 3.0.\n */\n BRILLIANT_DIAMOND_AND_SHINING_PEARL: 23,\n /**\n * @deprecated The endpoint names this `lets-go-pikachu-lets-go-eevee` now.\n * Use {@link VERSION_GROUPS.LETS_GO_PIKACHU_LETS_GO_EEVEE}. Removed in 3.0.\n */\n LETS_GO: 19,\n} as const;\n","export const ITEM_ATTRIBUTES = {\n COUNTABLE: 1,\n CONSUMABLE: 2,\n USABLE_OVERWORLD: 3,\n USABLE_IN_BATTLE: 4,\n HOLDABLE: 5,\n HOLDABLE_PASSIVE: 6,\n HOLDABLE_ACTIVE: 7,\n UNDERGROUND: 8,\n} as const;\n\nexport const ITEM_CATEGORIES = {\n STAT_BOOSTS: 1,\n EFFORT_DROP: 2,\n MEDICINE: 3,\n OTHER: 4,\n IN_A_PINCH: 5,\n PICKY_HEALING: 6,\n TYPE_PROTECTION: 7,\n BAKING_ONLY: 8,\n COLLECTIBLES: 9,\n EVOLUTION: 10,\n SPELUNKING: 11,\n HELD_ITEMS: 12,\n CHOICE: 13,\n EFFORT_TRAINING: 14,\n BAD_HELD_ITEMS: 15,\n TRAINING: 16,\n PLATES: 17,\n SPECIES_SPECIFIC: 18,\n TYPE_ENHANCEMENT: 19,\n EVENT_ITEMS: 20,\n GAMEPLAY: 21,\n PLOT_ADVANCEMENT: 22,\n UNUSED: 23,\n LOOT: 24,\n ALL_MAIL: 25,\n VITAMINS: 26,\n HEALING: 27,\n PP_RECOVERY: 28,\n REVIVAL: 29,\n STATUS_CURES: 30,\n MULCH: 32,\n SPECIAL_BALLS: 33,\n STANDARD_BALLS: 34,\n DEX_COMPLETION: 35,\n SCARVES: 36,\n ALL_MACHINES: 37,\n FLUTES: 38,\n APRICORN_BALLS: 39,\n APRICORN_BOX: 40,\n DATA_CARDS: 41,\n JEWELS: 42,\n MIRACLE_SHOOTER: 43,\n MEGA_STONES: 44,\n MEMORIES: 45,\n Z_CRYSTALS: 46,\n SPECIES_CANDIES: 47,\n CATCHING_BONUS: 48,\n DYNAMAX_CRYSTALS: 49,\n NATURE_MINTS: 50,\n CURRY_INGREDIENTS: 51,\n TERA_SHARD: 52,\n SANDWICH_INGREDIENTS: 53,\n TM_MATERIALS: 54,\n PICNIC: 55,\n /**\n * @deprecated Misspelled: the endpoint names this `dynamax-crystals`.\n * Use {@link ITEM_CATEGORIES.DYNAMAX_CRYSTALS}. Removed in 3.0.\n */\n DYNAMAX_CRISTALS: 49,\n} as const;\n\nexport const ITEM_FLING_EFFECTS = {\n BADLY_POISON: 1,\n BURN: 2,\n BERRY_EFFECT: 3,\n HERB_EFFECT: 4,\n PARALYZE: 5,\n POISON: 6,\n FLINCH: 7,\n} as const;\n\nexport const ITEM_POCKETS = {\n MISC: 1,\n MEDICINE: 2,\n POKEBALLS: 3,\n MACHINES: 4,\n BERRIES: 5,\n MAIL: 6,\n BATTLE: 7,\n KEY: 8,\n} as const;\n","export const REGIONS = {\n KANTO: 1,\n JOHTO: 2,\n HOENN: 3,\n SINNOH: 4,\n UNOVA: 5,\n KALOS: 6,\n ALOLA: 7,\n GALAR: 8,\n HISUI: 9,\n PALDEA: 10,\n ORRE: 11,\n} as const;\n\nexport const PAL_PARK_AREAS = {\n FOREST: 1,\n FIELD: 2,\n MOUNTAIN: 3,\n POND: 4,\n SEA: 5,\n} as const;\n","export const MOVE_AILMENTS = {\n UNKNOWN: -1,\n NONE: 0,\n PARALYSIS: 1,\n SLEEP: 2,\n FREEZE: 3,\n BURN: 4,\n POISON: 5,\n CONFUSION: 6,\n INFATUATION: 7,\n TRAP: 8,\n NIGHTMARE: 9,\n TORMENT: 12,\n DISABLE: 13,\n YAWN: 14,\n HEAL_BLOCK: 15,\n NO_TYPE_IMMUNITY: 17,\n LEECH_SEED: 18,\n EMBARGO: 19,\n PERISH_SONG: 20,\n INGRAIN: 21,\n SILENCE: 24,\n TAR_SHOT: 42,\n} as const;\n\nexport const MOVE_BATTLE_STYLES = {\n ATTACK: 1,\n DEFENSE: 2,\n SUPPORT: 3,\n} as const;\n\nexport const MOVE_CATEGORIES = {\n DAMAGE: 0,\n AILMENT: 1,\n NET_GOOD_STATS: 2,\n HEAL: 3,\n DAMAGE_AILMENT: 4,\n SWAGGER: 5,\n DAMAGE_LOWER: 6,\n DAMAGE_RAISE: 7,\n DAMAGE_HEAL: 8,\n OHKO: 9,\n WHOLE_FIELD_EFFECT: 10,\n FIELD_EFFECT: 11,\n FORCE_SWITCH: 12,\n UNIQUE: 13,\n} as const;\n\nexport const MOVE_DAMAGE_CLASSES = {\n STATUS: 1,\n PHYSICAL: 2,\n SPECIAL: 3,\n} as const;\n\nexport const MOVE_LEARN_METHODS = {\n LEVEL_UP: 1,\n EGG: 2,\n TUTOR: 3,\n MACHINE: 4,\n STADIUM_SURFING_PIKACHU: 5,\n LIGHT_BALL_EGG: 6,\n COLOSSEUM_PURIFICATION: 7,\n XD_SHADOW: 8,\n XD_PURIFICATION: 9,\n FORM_CHANGE: 10,\n ZYGARDE_CUBE: 11,\n TRAIN: 12,\n} as const;\n\nexport const MOVE_TARGETS = {\n SPECIFIC_MOVE: 1,\n SELECTED_POKEMON_ME_FIRST: 2,\n ALLY: 3,\n USERS_FIELD: 4,\n USER_OR_ALLY: 5,\n OPPONENTS_FIELD: 6,\n USER: 7,\n RANDOM_OPPONENT: 8,\n ALL_OTHER_POKEMON: 9,\n SELECTED_POKEMON: 10,\n ALL_OPPONENTS: 11,\n ENTIRE_FIELD: 12,\n USER_AND_ALLIES: 13,\n ALL_POKEMON: 14,\n ALL_ALLIES: 15,\n FAINTING_POKEMON: 16,\n /**\n * @deprecated Misspelled: the endpoint names this `user-and-allies`.\n * Use {@link MOVE_TARGETS.USER_AND_ALLIES}. Removed in 3.0.\n */\n USER_AND_ALIES: 13,\n} as const;\n","export const EGG_GROUPS = {\n MONSTER: 1,\n WATER1: 2,\n BUG: 3,\n FLYING: 4,\n GROUND: 5,\n FAIRY: 6,\n PLANT: 7,\n HUMANSHAPE: 8,\n WATER3: 9,\n MINERAL: 10,\n INDETERMINATE: 11,\n WATER2: 12,\n DITTO: 13,\n DRAGON: 14,\n NO_EGGS: 15,\n} as const;\n\nexport const GENDERS = {\n FEMALE: 1,\n MALE: 2,\n GENDERLESS: 3,\n} as const;\n\nexport const GROWTH_RATES = {\n SLOW: 1,\n MEDIUM: 2,\n FAST: 3,\n MEDIUM_SLOW: 4,\n SLOW_THEN_VERY_FAST: 5,\n FAST_THEN_VERY_SLOW: 6,\n} as const;\n\nexport const NATURES = {\n HARDY: 1,\n BOLD: 2,\n MODEST: 3,\n CALM: 4,\n TIMID: 5,\n LONELY: 6,\n DOCILE: 7,\n MILD: 8,\n GENTLE: 9,\n HASTY: 10,\n ADAMANT: 11,\n IMPISH: 12,\n BASHFUL: 13,\n CAREFUL: 14,\n RASH: 15,\n JOLLY: 16,\n NAUGHTY: 17,\n LAX: 18,\n QUIRKY: 19,\n NAIVE: 20,\n BRAVE: 21,\n RELAXED: 22,\n QUIET: 23,\n SASSY: 24,\n SERIOUS: 25,\n} as const;\n\nexport const POKEATHLON_STATS = {\n SPEED: 1,\n POWER: 2,\n SKILL: 3,\n STAMINA: 4,\n JUMP: 5,\n} as const;\n\nexport const POKEMON_COLORS = {\n BLACK: 1,\n BLUE: 2,\n BROWN: 3,\n GRAY: 4,\n GREEN: 5,\n PINK: 6,\n PURPLE: 7,\n RED: 8,\n WHITE: 9,\n YELLOW: 10,\n} as const;\n\nexport const POKEMON_HABITATS = {\n CAVE: 1,\n FOREST: 2,\n GRASSLAND: 3,\n MOUNTAIN: 4,\n RARE: 5,\n ROUGH_TERRAIN: 6,\n SEA: 7,\n URBAN: 8,\n WATERS_EDGE: 9,\n /**\n * @deprecated Misspelled: the endpoint names this `mountain`.\n * Use {@link POKEMON_HABITATS.MOUNTAIN}. Removed in 3.0.\n */\n MONTAIN: 4,\n} as const;\n\nexport const POKEMON_SHAPES = {\n BALL: 1,\n SQUIGGLE: 2,\n FISH: 3,\n ARMS: 4,\n BLOB: 5,\n UPRIGHT: 6,\n LEGS: 7,\n QUADRUPED: 8,\n WINGS: 9,\n TENTACLES: 10,\n HEADS: 11,\n HUMANOID: 12,\n BUG_WINGS: 13,\n ARMOR: 14,\n} as const;\n\nexport const STATS = {\n HP: 1,\n ATTACK: 2,\n DEFENSE: 3,\n SPECIAL_ATTACK: 4,\n SPECIAL_DEFENSE: 5,\n SPEED: 6,\n ACCURACY: 7,\n EVASION: 8,\n SPECIAL: 9,\n} as const;\n\nexport const TYPES = {\n NORMAL: 1,\n FIGHTING: 2,\n FLYING: 3,\n POISON: 4,\n GROUND: 5,\n ROCK: 6,\n BUG: 7,\n GHOST: 8,\n STEEL: 9,\n FIRE: 10,\n WATER: 11,\n GRASS: 12,\n ELECTRIC: 13,\n PSYCHIC: 14,\n ICE: 15,\n DRAGON: 16,\n DARK: 17,\n FAIRY: 18,\n STELLAR: 19,\n UNKNOWN: 10_001,\n SHADOW: 10_002,\n} as const;\n\n/**\n * ## Type Name\n * A battle type as the PokéAPI names it, which is what a\n * `NamedAPIResource<Type>` carries and what the type chart is keyed by.\n *\n * The eighteen types a Pokémon can be, and `stellar`, which is a Tera type and\n * nothing else. `unknown` and `shadow` are in {@link TYPES} but not here: they\n * are artefacts of Generation II's internals and of Colosseum/XD, they appear in\n * no damage relation, and a table keyed by them would be a table with two entries\n * nothing can ever fill.\n *\n * Written out rather than derived from {@link TYPES}, for the same reason\n * `GenerationName` is: the set is closed, and the two exclusions are a decision\n * rather than a transformation.\n */\nexport type TypeName =\n | \"normal\"\n | \"fighting\"\n | \"flying\"\n | \"poison\"\n | \"ground\"\n | \"rock\"\n | \"bug\"\n | \"ghost\"\n | \"steel\"\n | \"fire\"\n | \"water\"\n | \"grass\"\n | \"electric\"\n | \"psychic\"\n | \"ice\"\n | \"dragon\"\n | \"dark\"\n | \"fairy\"\n | \"stellar\";\n","export const BASE_URL = {\n REST: \"https://pokeapi.co/api/v2\",\n /** Root of the sprite repository the API's own sprite URLs point at. */\n SPRITES: \"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites\",\n} as const;\n","export const LANGUAGES = {\n JA_HRKT: 1,\n JA_ROMA: 2,\n KO: 3,\n ZH_HANT: 4,\n FR: 5,\n DE: 6,\n ES: 7,\n IT: 8,\n EN: 9,\n CS: 10,\n JA: 11,\n ZH_HANS: 12,\n PT_BR: 13,\n ES_419: 14,\n} as const;\n","export * from \"./berries\";\nexport * from \"./contests\";\nexport * from \"./currencies\";\nexport * from \"./encounters\";\nexport * from \"./endpoints\";\nexport * from \"./evolutions\";\nexport * from \"./games\";\nexport * from \"./items\";\nexport * from \"./locations\";\nexport * from \"./moves\";\nexport * from \"./pokemon\";\nexport * from \"./urls\";\nexport * from \"./utilities\";\n","/** Five minutes. */\nconst DEFAULT_TTL = 300_000;\nconst DEFAULT_MAX_ENTRIES = 500;\n\n/**\n * ## Cache Store\n * The contract a client uses to cache responses, keyed by request URL.\n *\n * Every method may return a promise, so remote backends (Redis, KV stores) work\n * as-is. Values cross this boundary as parsed objects; expiry is the store's own\n * business.\n */\nexport interface CacheStore {\n get(key: string): unknown | Promise<unknown>;\n set(key: string, value: unknown): void | Promise<void>;\n delete?(key: string): void | Promise<void>;\n clear?(): void | Promise<void>;\n}\n\n/** Default namespace for the keys {@link WebStorageCache} owns. */\nconst DEFAULT_PREFIX = \"pokenode:\";\n\n/**\n * How many entries a bounded store keeps.\n *\n * A non-finite limit falls back to the default rather than being clamped:\n * `size >= NaN` is never true, and a bound that is never reached is not a bound\n * — `maxEntries` is exactly the sort of option that arrives as\n * `Number(process.env.CACHE_SIZE)`. Zero and below keep nothing.\n */\nconst entryLimit = (value: number | undefined, fallback: number): number =>\n value !== undefined && Number.isFinite(value) ? Math.max(Math.floor(value), 0) : fallback;\n\n/**\n * ## Memory Cache Options\n * Used to configure the default in-memory store.\n */\nexport interface MemoryCacheOptions {\n /** How long a cached response stays fresh, in milliseconds. Defaults to 5 minutes. */\n ttl?: number;\n /**\n * Maximum number of responses kept. The least recently used entry is evicted.\n * Defaults to 500; zero keeps none.\n */\n maxEntries?: number;\n}\n\ninterface CacheEntry {\n value: unknown;\n expiresAt: number;\n}\n\n/**\n * ## Memory Cache\n * The default {@link CacheStore}: a bounded, time-to-live cache held in memory.\n *\n * Values are stored and returned by reference — mutating a response also mutates\n * what later cache hits return, so treat responses as read-only.\n */\nexport class MemoryCache implements CacheStore {\n private readonly entries = new Map<string, CacheEntry>();\n private readonly ttl: number;\n private readonly maxEntries: number;\n\n constructor(options?: MemoryCacheOptions) {\n this.ttl = options?.ttl ?? DEFAULT_TTL;\n this.maxEntries = entryLimit(options?.maxEntries, DEFAULT_MAX_ENTRIES);\n }\n\n get(key: string): unknown {\n const entry = this.entries.get(key);\n\n if (!entry) {\n return undefined;\n }\n\n if (entry.expiresAt <= Date.now()) {\n this.entries.delete(key);\n return undefined;\n }\n\n // Re-insert so `entries` stays ordered least- to most-recently used.\n this.entries.delete(key);\n this.entries.set(key, entry);\n\n return entry.value;\n }\n\n set(key: string, value: unknown): void {\n // Delete first so an update moves the key to the most-recently-used end.\n this.entries.delete(key);\n\n // A store with no room keeps nothing, rather than the one entry an eviction\n // that has nothing to evict would leave behind.\n if (this.maxEntries === 0) {\n return;\n }\n\n if (this.entries.size >= this.maxEntries) {\n const oldest = this.entries.keys().next();\n if (!oldest.done) {\n this.entries.delete(oldest.value);\n }\n }\n\n this.entries.set(key, { value, expiresAt: Date.now() + this.ttl });\n }\n\n delete(key: string): void {\n this.entries.delete(key);\n }\n\n clear(): void {\n this.entries.clear();\n }\n}\n\n/** How many URLs an {@link EtagStore} remembers before evicting the oldest. */\nconst DEFAULT_ETAG_ENTRIES = 500;\n\n/**\n * ## Etag Entry\n * What a URL last answered with, and the validator that says so.\n */\nexport interface EtagEntry {\n /** The `ETag` the response carried. */\n etag: string;\n /** The parsed body that `etag` identifies. */\n value: unknown;\n}\n\n/**\n * ## Etag Store Options\n * Used to configure an {@link EtagStore}.\n */\nexport interface EtagStoreOptions {\n /**\n * How many URLs to remember. The least recently used is evicted. Defaults to\n * 500; zero remembers none.\n */\n maxEntries?: number;\n}\n\n/**\n * ## Etag Store\n * Remembers the `ETag` each URL answered with, and the body it identified, so an\n * expired cache entry can be revalidated instead of downloaded again.\n *\n * Deliberately not a {@link CacheStore}: the two answer different questions. A\n * `CacheStore` says \"this response is still fresh, use it\"; this says \"here is\n * what the response was last time, ask the server whether it still holds\". They\n * are kept apart so that a store someone else owns — a shared Redis — is never\n * given a second key shape, and `cache.get(url)` keeps returning the resource\n * itself.\n *\n * Entries live in memory and are never persisted: an `ETag` is only worth what\n * the body beside it is, and the body is what would cost memory to keep.\n */\nexport class EtagStore {\n private readonly entries = new Map<string, EtagEntry>();\n private readonly maxEntries: number;\n\n constructor(options?: EtagStoreOptions) {\n this.maxEntries = entryLimit(options?.maxEntries, DEFAULT_ETAG_ENTRIES);\n }\n\n get(url: string): EtagEntry | undefined {\n const entry = this.entries.get(url);\n\n if (!entry) {\n return undefined;\n }\n\n // Re-insert so `entries` stays ordered least- to most-recently used.\n this.entries.delete(url);\n this.entries.set(url, entry);\n\n return entry;\n }\n\n set(url: string, entry: EtagEntry): void {\n this.entries.delete(url);\n\n if (this.maxEntries === 0) {\n return;\n }\n\n if (this.entries.size >= this.maxEntries) {\n const oldest = this.entries.keys().next();\n\n if (!oldest.done) {\n this.entries.delete(oldest.value);\n }\n }\n\n this.entries.set(url, entry);\n }\n\n clear(): void {\n this.entries.clear();\n }\n}\n\n/**\n * ## Web Storage Like\n * The part of the browser's `Storage` interface a {@link WebStorageCache} uses.\n *\n * Declared structurally rather than as the DOM's `Storage`: the package compiles\n * without `lib.dom`, and stays usable anywhere the same shape exists.\n *\n * Every method may return a promise, so a React Native `AsyncStorage` works as-is.\n * Key enumeration is the one place the two shapes differ: `Storage` exposes\n * `length` and `key(index)`, `AsyncStorage` exposes `getAllKeys`, and a property\n * cannot be awaited — so both are accepted, and a storage offering neither still\n * caches; it just never evicts or clears.\n */\nexport interface WebStorageLike {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n /** Every key held, this store's and the application's alike. */\n getAllKeys?(): readonly string[] | Promise<readonly string[]>;\n key?(index: number): string | null;\n readonly length?: number;\n}\n\n/**\n * ## Web Storage Cache Options\n * Used to configure a store backed by `localStorage` or `sessionStorage`.\n */\nexport interface WebStorageCacheOptions {\n /**\n * Where entries are kept. Pass `localStorage`, `sessionStorage`, a React Native\n * `AsyncStorage`, or anything else matching {@link WebStorageLike}.\n */\n storage: WebStorageLike;\n /** How long a cached response stays fresh, in milliseconds. Defaults to 5 minutes. */\n ttl?: number;\n /** Namespace for the keys this store writes. Defaults to `pokenode:`. */\n prefix?: string;\n}\n\n/**\n * ## Web Storage Cache\n * A {@link CacheStore} backed by `localStorage` or `sessionStorage`, so a cached\n * response survives a page reload.\n *\n * ```ts\n * const api = new PokemonClient({ cache: new WebStorageCache({ storage: localStorage }) });\n * ```\n *\n * Only keys under {@link WebStorageCacheOptions.prefix} are ever read, evicted or\n * cleared — the storage is assumed to be shared with the surrounding application.\n *\n * Values round-trip through JSON, so unlike {@link MemoryCache} every hit returns a\n * fresh copy. Anything a `JSON.stringify` cannot represent does not survive, which\n * covers every PokéAPI response.\n *\n * A storage that throws instead of answering is treated as empty: a read is a miss\n * and a write is dropped, because neither is worth failing the request that\n * triggered it over.\n */\nexport class WebStorageCache implements CacheStore {\n private readonly storage: WebStorageLike;\n private readonly ttl: number;\n private readonly prefix: string;\n\n constructor(options: WebStorageCacheOptions) {\n this.storage = options.storage;\n this.ttl = options.ttl ?? DEFAULT_TTL;\n this.prefix = options.prefix ?? DEFAULT_PREFIX;\n }\n\n async get(key: string): Promise<unknown> {\n const entry = await this.read(this.prefix + key);\n\n if (!entry) {\n return undefined;\n }\n\n if (entry.expiresAt <= Date.now()) {\n await this.remove(this.prefix + key);\n return undefined;\n }\n\n return entry.value;\n }\n\n async set(key: string, value: unknown): Promise<void> {\n const entry = JSON.stringify({ value, expiresAt: Date.now() + this.ttl });\n\n try {\n await this.storage.setItem(this.prefix + key, entry);\n } catch {\n // Out of quota, most likely. Make room among this store's own keys and try\n // once more; a cache write that cannot land must not fail the request that\n // triggered it, so a second failure is dropped.\n await this.evict();\n\n try {\n await this.storage.setItem(this.prefix + key, entry);\n } catch {\n return;\n }\n }\n }\n\n async delete(key: string): Promise<void> {\n await this.storage.removeItem(this.prefix + key);\n }\n\n async clear(): Promise<void> {\n for (const key of await this.ownKeys()) {\n await this.remove(key);\n }\n }\n\n /** Reads a namespaced key, treating unreadable content as a miss. */\n private async read(key: string): Promise<CacheEntry | undefined> {\n let stored: string | null;\n\n try {\n stored = await this.storage.getItem(key);\n } catch {\n // A storage that refuses to be read — Safari with storage blocked, a shim\n // that throws — is a cache miss, not a failed request. The response the\n // caller asked for is still one fetch away.\n return undefined;\n }\n\n if (stored === null) {\n return undefined;\n }\n\n try {\n return JSON.parse(stored) as CacheEntry;\n } catch {\n // Written by an older version, or by something else under the same prefix.\n await this.remove(key);\n return undefined;\n }\n }\n\n /**\n * Frees space by dropping expired entries, falling back to the ones closest to\n * expiring when nothing has expired yet.\n */\n private async evict(): Promise<void> {\n const keys = await this.ownKeys();\n const entries = await Promise.all(\n keys.map(async (key) => ({ key, expiresAt: (await this.read(key))?.expiresAt })),\n );\n const now = Date.now();\n const expired = entries.filter(({ expiresAt }) => expiresAt === undefined || expiresAt <= now);\n\n if (expired.length > 0) {\n for (const { key } of expired) {\n await this.remove(key);\n }\n\n return;\n }\n\n const soonest = entries.sort((a, b) => (a.expiresAt ?? 0) - (b.expiresAt ?? 0));\n\n for (const { key } of soonest.slice(0, Math.ceil(soonest.length / 4))) {\n await this.remove(key);\n }\n }\n\n /**\n * Collects this store's keys before any removal: `key(index)` walks a list that\n * shifts underneath a loop that deletes as it goes.\n */\n private async ownKeys(): Promise<string[]> {\n return (await this.allKeys()).filter((key) => key.startsWith(this.prefix));\n }\n\n /**\n * Every key the storage holds, however it is willing to list them. A storage\n * offering no enumeration at all reports none, which leaves eviction and\n * `clear` as no-ops rather than an error on a path that only tidies up.\n */\n private async allKeys(): Promise<string[]> {\n try {\n if (this.storage.getAllKeys !== undefined) {\n return [...(await this.storage.getAllKeys())];\n }\n\n const { key, length } = this.storage;\n\n if (key === undefined || length === undefined) {\n return [];\n }\n\n const keys: string[] = [];\n\n for (let index = 0; index < length; index += 1) {\n const found = key.call(this.storage, index);\n\n if (found !== null) {\n keys.push(found);\n }\n }\n\n return keys;\n } catch {\n return [];\n }\n }\n\n /** Removes a key on a path that is only tidying up, where a refusal is moot. */\n private async remove(key: string): Promise<void> {\n try {\n await this.storage.removeItem(key);\n } catch {\n // The entry stays until the storage lets it go; a read of it is a miss\n // either way, since it is expired or unparseable.\n }\n }\n}\n","/**\n * Brands the error, so the guard can match on it instead of the prototype chain:\n * a tree loading both the ESM and the CJS build has two distinct classes.\n */\nconst ERROR_KIND = \"pokenode:http\";\n\n/**\n * ## Pokenode Error\n * Thrown when the PokéAPI answers with a non-2xx status. Transport failures are\n * not wrapped — the native error propagates untouched.\n */\nexport class PokenodeError extends Error {\n override readonly name = \"PokenodeError\";\n readonly kind = ERROR_KIND;\n\n /** HTTP status code of the response. */\n readonly status: number;\n /** HTTP status text of the response. */\n readonly statusText: string;\n /** URL that produced the error. */\n readonly url: string;\n /** Parsed response body, when the error response carried JSON. */\n readonly body: unknown;\n\n /**\n * @param message Overrides the default text, for a status whose failure is not\n * self-explanatory.\n */\n constructor(response: Response, body: unknown, message?: string) {\n super(message ?? `Request to ${response.url} failed with status ${response.status}`);\n\n this.status = response.status;\n this.statusText = response.statusText;\n this.url = response.url;\n this.body = body;\n }\n\n /** Whether the error came from a pokenode-ts client. */\n static isPokenodeError(error: unknown): error is PokenodeError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"kind\" in error &&\n (error as { kind: unknown }).kind === ERROR_KIND\n );\n }\n}\n\n/**\n * Builds a {@link PokenodeError} from a failed response, reading the body when\n * it is JSON. The PokéAPI answers 404s with plain text, so a parse failure is\n * expected and leaves `body` undefined.\n */\nexport const toPokenodeError = async (\n response: Response,\n message?: string,\n): Promise<PokenodeError> => {\n let body: unknown;\n\n try {\n body = await response.json();\n } catch {\n body = undefined;\n }\n\n return new PokenodeError(response, body, message);\n};\n","/**\n * Fields shared by every payload.\n *\n * The text is carried twice on purpose. pino, bunyan and roarr read `msg`;\n * winston reads `message`. Sending both is what lets a logger from either family\n * be passed straight in, with no adapter to write and nothing logged as\n * `undefined`.\n */\ninterface LogFields {\n /** Which point of the request lifecycle this is, for filtering. */\n event: \"request\" | \"response\" | \"retry\" | \"cancelled\" | \"error\";\n msg: string;\n message: string;\n /** The request URL, with any credentials the base URL carried removed. */\n url: string;\n}\n\n/**\n * ## Log Request Payload\n * A request is about to be resolved, from cache or over the network.\n */\nexport interface LogRequestPayload extends LogFields {\n event: \"request\";\n /** The HTTP method, uppercase, as RFC 9110 and OpenTelemetry both expect. */\n method: string;\n}\n\n/**\n * ## Log Response Payload\n * A response was produced.\n */\nexport interface LogResponsePayload extends LogFields {\n event: \"response\";\n status: number;\n /**\n * Where the response came from.\n *\n * - `network` — a round trip was made.\n * - `cache` — served by the {@link CacheStore}; nothing left the process.\n * - `in-flight` — an identical request was already on the wire and this caller\n * shared it, so it made no round trip of its own.\n * - `revalidated` — a round trip was made, the API answered 304, and the body\n * already held for that URL was reused. Cheap, but not free.\n *\n * Counting `network` and `revalidated` gives the number of requests the\n * PokéAPI actually saw. Every caller reports, so counting all four gives the\n * number of calls the application made.\n */\n source: \"network\" | \"cache\" | \"in-flight\" | \"revalidated\";\n /** How long the client took to resolve the request, in milliseconds. */\n durationMs: number;\n}\n\n/**\n * ## Log Retry Payload\n * An attempt failed and another one is coming.\n *\n * Only emitted when `retry` is configured, and never for the attempt that gives\n * up — that one is a `response` or an `error` like any other. Counting these\n * gives the round trips the PokéAPI saw beyond the ones it answered.\n */\nexport interface LogRetryPayload extends LogFields {\n event: \"retry\";\n /** Which attempt just failed, counting from one. */\n attempt: number;\n /** How long the client will wait before the next one, in milliseconds. */\n delayMs: number;\n /** The status that failed. Absent when the attempt never got a response. */\n status?: number;\n}\n\n/**\n * ## Log Cancelled Payload\n * A request was cancelled by the scope it was made through.\n *\n * A caller that hangs up asked for this, so it is not a failure and does not\n * reach `error`: a handler that scopes every request would otherwise report its\n * own timeouts as its error rate. Counting `response` and `cancelled` together\n * accounts for every `request` logged.\n */\nexport interface LogCancelledPayload extends LogFields {\n event: \"cancelled\";\n /** `signal.reason`, or the `TimeoutError` a scoped timeout raised. */\n reason: unknown;\n /** How long the request had been running when it was cancelled, in milliseconds. */\n durationMs: number;\n}\n\n/**\n * ## Log Error Payload\n * A request failed.\n *\n * The error is carried twice for the same reason the message is: pino runs its\n * error serializer on `err` and nothing else, so an `Error` under any other key\n * would reach the log as `{}` — no message, no stack.\n */\nexport interface LogErrorPayload extends LogFields {\n event: \"error\";\n /** Whatever `fetch` or the API produced. */\n err: unknown;\n error: unknown;\n}\n\n/**\n * ## Logger\n * Where a client reports what it did.\n *\n * Deliberately the shape every logging library already has, so one can be passed\n * without glue:\n *\n * ```ts\n * new PokemonClient({ logger: pino() });\n * new PokemonClient({ logger: console });\n * new PokemonClient({ logger: winston.createLogger() });\n * ```\n *\n * Requests, responses and cancellations go to `debug`; failures go to `error`.\n * Nothing is logged unless a logger is passed, and a client never picks a level\n * of its own.\n */\nexport interface Logger {\n debug(\n payload: LogRequestPayload | LogResponsePayload | LogRetryPayload | LogCancelledPayload,\n ): void;\n error(payload: LogErrorPayload): void;\n}\n\n/**\n * Builds the message keys both logging families expect. Internal — the payload\n * types are the public contract.\n */\nexport const logMessage = (text: string): { msg: string; message: string } => ({\n msg: text,\n message: text,\n});\n\n/**\n * A {@link Logger} that writes the request lifecycle to the console as one\n * formatted line per event.\n *\n * `console` itself is a valid {@link Logger} and logs the payload as an object;\n * this is for when the terminal should stay readable.\n */\nexport const consoleLogger: Logger = {\n debug(payload) {\n if (payload.event === \"request\") {\n console.log(`[ Request Config ] ${payload.method} | ${payload.url}`);\n return;\n }\n\n if (payload.event === \"retry\") {\n console.log(\n `[ Retry ] ATTEMPT ${payload.attempt} | STATUS ${payload.status ?? \"NONE\"} | IN ${payload.delayMs.toFixed(0)}ms | ${payload.url}`,\n );\n return;\n }\n\n if (payload.event === \"cancelled\") {\n console.log(`[ Cancelled ] ${payload.url} | AFTER ${payload.durationMs.toFixed(1)}ms`);\n return;\n }\n\n console.log(\n `[ Response ] STATUS ${payload.status} | ${payload.source.toUpperCase()} | ${payload.durationMs.toFixed(1)}ms`,\n );\n },\n\n error({ url, err }) {\n const { name, message } =\n err instanceof Error ? err : { name: \"UNKNOWN\", message: String(err) };\n\n console.error(`[ Response Error ] ${url} | CODE ${name} | ${message}`);\n },\n};\n","/**\n * A request already on the wire, and what it takes to cancel it.\n *\n * `waiters` counts the callers still interested. The request is aborted only\n * when the last of them has left, so one caller giving up does not cancel the\n * round trip the others are sharing.\n */\ninterface Request<T> {\n promise: Promise<T>;\n /** Absent when the caller that started the request had nothing to cancel it with. */\n controller: AbortController | undefined;\n waiters: number;\n}\n\n/** A resolved request, and whether this caller paid for it. */\nexport interface Shared<T> {\n value: T;\n /** Whether an identical request was already on the wire and this caller joined it. */\n joined: boolean;\n}\n\n/**\n * ## In Flight\n * The requests currently on the wire, keyed by URL, so concurrent callers asking\n * for the same one share a single round trip.\n *\n * Held by a transport's shared state and passed by reference, so a scoped\n * transport joins the requests already running rather than starting its own.\n *\n * Internal, and deliberately ignorant of what a request resolves to: it owns the\n * bookkeeping — who is still waiting, who may cancel, when an entry is forgotten\n * — and nothing about HTTP.\n */\nexport class InFlight<T> {\n private readonly requests = new Map<string, Request<T>>();\n\n /**\n * Resolves `key` through the request already running for it, or through a new\n * one started by `start`.\n *\n * `start` is handed the signal to cancel with, which is not the caller's: the\n * callers sharing a request come and go, and only the last one to leave may\n * cancel it.\n */\n async share(\n key: string,\n signal: AbortSignal | undefined,\n start: (signal: AbortSignal | undefined) => Promise<T>,\n ): Promise<Shared<T>> {\n const pending = this.requests.get(key);\n const entry = pending ?? this.dispatch(key, signal, start);\n\n return { value: await this.join(key, entry, signal), joined: pending !== undefined };\n }\n\n /** Issues a request and remembers it, so a concurrent caller can share it. */\n private dispatch(\n key: string,\n signal: AbortSignal | undefined,\n start: (signal: AbortSignal | undefined) => Promise<T>,\n ): Request<T> {\n const controller = signal ? new AbortController() : undefined;\n const entry: Request<T> = {\n promise: start(controller?.signal),\n controller,\n waiters: 0,\n };\n\n entry.promise = entry.promise.finally(() => this.release(key, entry));\n\n // A request abandoned by every caller rejects with nobody left awaiting it.\n // This handler exists only so that rejection is not unhandled; each caller\n // still sees the failure through its own `join`.\n entry.promise.catch(() => {});\n\n this.requests.set(key, entry);\n\n return entry;\n }\n\n /**\n * Forgets a request, unless a later caller has already replaced it: a request\n * that was aborted leaves the map before it settles, and the one dispatched in\n * its place must survive its predecessor finishing.\n */\n private release(key: string, entry: Request<T>): void {\n if (this.requests.get(key) === entry) {\n this.requests.delete(key);\n }\n }\n\n /**\n * Awaits a request, cancelling it if this caller was the last one interested.\n *\n * A caller with no signal never leaves early, so it holds the request open for\n * everyone — including a scoped caller that joined later and gave up.\n */\n private join(key: string, entry: Request<T>, signal: AbortSignal | undefined): Promise<T> {\n entry.waiters += 1;\n\n if (!signal) {\n return entry.promise;\n }\n\n return new Promise<T>((resolve, reject) => {\n const leave = (): void => {\n entry.waiters -= 1;\n\n if (entry.waiters > 0) {\n return;\n }\n\n // Dropped from the map before the abort settles it: a caller arriving in\n // between would otherwise join a request already on its way out and\n // inherit an abort it never asked for.\n this.release(key, entry);\n entry.controller?.abort(signal.reason);\n };\n\n if (signal.aborted) {\n leave();\n reject(signal.reason);\n return;\n }\n\n const onAbort = (): void => {\n leave();\n reject(signal.reason);\n };\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n\n entry.promise.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error);\n },\n );\n });\n }\n}\n","/**\n * How many requests the helpers that fetch many resources at once will run in\n * parallel. Kept low on purpose: see the PokéAPI fair-use policy.\n */\nexport const DEFAULT_CONCURRENCY = 4;\n\n/**\n * Runs `task` over `items` with at most `concurrency` of them in flight, and\n * returns the results in the order the items came in.\n *\n * Internal: the PokéAPI's fair-use policy asks clients not to flood it, so the\n * places that resolve many links at once go through here rather than\n * `Promise.all`.\n *\n * The first failure stops the pool — workers check before taking more work, so\n * a rejection does not leave a tail of requests running for a result nobody will\n * read.\n */\nexport const mapWithConcurrency = async <I, O>(\n items: readonly I[],\n concurrency: number,\n task: (item: I) => Promise<O>,\n): Promise<O[]> => {\n const results = new Array<O>(items.length);\n let cursor = 0;\n let failed = false;\n\n const worker = async (): Promise<void> => {\n while (cursor < items.length && !failed) {\n const index = cursor;\n cursor += 1;\n\n try {\n results[index] = await task(items[index] as I);\n } catch (error) {\n failed = true;\n throw error;\n }\n }\n };\n\n // A non-finite count falls back to the default rather than being clamped:\n // `Math.max(NaN, 1)` is `NaN`, `Array.from({ length: NaN })` is empty, and a\n // pool with no workers returns a hole per item instead of failing. This is\n // exactly the sort of option that arrives as `Number(process.env.CONCURRENCY)`.\n const requested = Number.isFinite(concurrency) ? concurrency : DEFAULT_CONCURRENCY;\n const workers = Array.from({ length: Math.min(Math.max(requested, 1), items.length) }, () =>\n worker(),\n );\n\n await Promise.all(workers);\n\n return results;\n};\n","import type { ListFn, PaginateOptions } from \"../clients/base\";\nimport type { APIResource } from \"../models/common/resource\";\nimport { DEFAULT_CONCURRENCY, mapWithConcurrency } from \"./pool\";\n\n/**\n * The PokéAPI's own default, and `Transport.list`'s, so a walk pages the way a\n * hand-written loop would.\n */\nexport const DEFAULT_PAGE_SIZE = 20;\n\n/**\n * Walks every page of a list, yielding one entry at a time.\n *\n * `resolve` is passed in rather than a transport: this module would otherwise\n * have to import the one that imports it.\n */\nexport async function* walk<T>(\n list: ListFn<APIResource<T>>,\n resolve: (link: APIResource<T>) => Promise<T>,\n options?: PaginateOptions,\n): AsyncGenerator<APIResource<T> | T> {\n const pageSize = options?.pageSize ?? DEFAULT_PAGE_SIZE;\n const concurrency = options?.concurrency ?? DEFAULT_CONCURRENCY;\n let offset = 0;\n\n while (true) {\n const page = await list(offset, pageSize);\n\n if (page.results.length === 0) {\n return;\n }\n\n if (options?.resolve) {\n // Resolved a page at a time: the order callers see stays the order the\n // API listed, however the requests within a page happen to finish.\n const resources = await mapWithConcurrency(page.results, concurrency, resolve);\n\n yield* resources;\n } else {\n yield* page.results;\n }\n\n offset += page.results.length;\n\n // A short page ends the walk on its own: `count` is upstream's word for how\n // much there is, and the results are the client's own evidence.\n if (page.results.length < pageSize || offset >= page.count) {\n return;\n }\n }\n}\n","import type { RetryOptions } from \"../clients/base\";\nimport { toPokenodeError } from \"../config/errors\";\nimport { type Logger, logMessage } from \"../config/logger\";\n\nconst DEFAULT_RETRY_ATTEMPTS = 3;\nconst DEFAULT_INITIAL_DELAY = 300;\nconst DEFAULT_MAX_DELAY = 5_000;\n/** Transient by definition: rate limiting, and the gateway failures around it. */\nconst DEFAULT_RETRY_STATUSES = [429, 500, 502, 503, 504];\n\n/**\n * How many attempts a request gets, the first one included. A fractional count\n * is rounded down, so `2.5` is two attempts rather than the three that\n * `attempt >= attempts` would otherwise allow.\n *\n * A non-finite count falls back to the default rather than being clamped:\n * `Math.max(NaN, 1)` is `NaN`, and an attempt loop bounded by `NaN` never ends.\n * `attempts` is exactly the sort of option that arrives as\n * `Number(process.env.RETRIES)`.\n */\nexport const attemptCount = (retry: RetryOptions | undefined): number => {\n if (!retry) {\n return 1;\n }\n\n const requested = retry.attempts ?? DEFAULT_RETRY_ATTEMPTS;\n\n return Number.isFinite(requested) ? Math.max(Math.floor(requested), 1) : DEFAULT_RETRY_ATTEMPTS;\n};\n\n/**\n * A configured wait, in milliseconds, or the default when it is not a number\n * this client can wait for.\n *\n * A non-finite value falls back for the reason given on {@link attemptCount}:\n * `setTimeout` reads a `NaN` delay as zero, and `x > NaN` is false, so an\n * unusable option spends every attempt at once — or accepts any `Retry-After`\n * it is sent.\n */\nconst delayOption = (value: number | undefined, fallback: number): number =>\n value !== undefined && Number.isFinite(value) ? Math.max(value, 0) : fallback;\n\n/**\n * Reads `Retry-After`, which RFC 9110 allows to be either a number of seconds or\n * an HTTP date. Returns milliseconds, or nothing when the header is absent or\n * unparseable.\n */\nconst toRetryAfterMs = (header: string | null): number | undefined => {\n if (header === null) {\n return undefined;\n }\n\n // `Number(\"\")` is a finite 0, which would read a blank header as permission to\n // retry immediately — the opposite of what the header is ever sent to say.\n const value = header.trim();\n\n if (value === \"\") {\n return undefined;\n }\n\n const seconds = Number(value);\n\n if (Number.isFinite(seconds)) {\n return Math.max(seconds, 0) * 1_000;\n }\n\n const date = Date.parse(value);\n\n return Number.isNaN(date) ? undefined : Math.max(date - Date.now(), 0);\n};\n\n/**\n * Whether an error is a request being cancelled rather than failing. A cancelled\n * request is never retried: someone asked for it to stop.\n */\nexport const isAbort = (error: unknown, signal: AbortSignal | undefined): boolean =>\n signal?.aborted === true ||\n (error instanceof Error && (error.name === \"AbortError\" || error.name === \"TimeoutError\"));\n\n/** Waits, unless the request is cancelled first. */\nconst sleep = (ms: number, signal: AbortSignal | undefined): Promise<void> =>\n new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n // Node holds the event loop open for a pending timer, so a wait between\n // attempts would keep a process that has nothing else to do alive for it.\n // Optional because a browser's `setTimeout` returns a number.\n timer.unref?.();\n\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(signal?.reason);\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n/**\n * How long `Retry-After` asks this client to wait, or nothing when the wait is\n * {@link backoff}'s to calculate.\n *\n * @throws {PokenodeError} If the failure is not one this client attempts again.\n */\nexport const retryDelay = async (\n response: Response,\n isLast: boolean,\n retry: RetryOptions | undefined,\n): Promise<number | undefined> => {\n const statuses = retry?.statuses ?? DEFAULT_RETRY_STATUSES;\n const maxDelay = delayOption(retry?.maxDelay, DEFAULT_MAX_DELAY);\n\n if (isLast || !statuses.includes(response.status)) {\n throw await toPokenodeError(response);\n }\n\n const retryAfter = toRetryAfterMs(response.headers.get(\"Retry-After\"));\n\n // Asked to wait longer than this client is willing to: waiting less is\n // exactly what the header exists to prevent, so the attempt is the last.\n if (retryAfter !== undefined && retryAfter > maxDelay) {\n throw await toPokenodeError(response);\n }\n\n return retryAfter;\n};\n\n/** What one wait between attempts needs to know. */\nexport interface BackoffOptions {\n url: string;\n attempt: number;\n /** Absent when the attempt failed before there was a response to read. */\n status: number | undefined;\n /** What `Retry-After` asked for, when it asked for anything. */\n retryAfter: number | undefined;\n signal: AbortSignal | undefined;\n retry: RetryOptions | undefined;\n logger: Logger | undefined;\n}\n\n/**\n * Waits before the next attempt, and says so through the logger.\n *\n * The wait is half of a doubling window plus jitter over the other half, so\n * clients that failed together do not come back together, and none of them\n * comes back immediately. `Retry-After` replaces the calculation outright.\n */\nexport const backoff = async (options: BackoffOptions): Promise<void> => {\n const { url, attempt, status, retryAfter, signal, retry, logger } = options;\n const initialDelay = delayOption(retry?.initialDelay, DEFAULT_INITIAL_DELAY);\n const maxDelay = delayOption(retry?.maxDelay, DEFAULT_MAX_DELAY);\n const window = Math.min(initialDelay * 2 ** (attempt - 1), maxDelay);\n const delayMs = retryAfter ?? window / 2 + Math.random() * (window / 2);\n\n logger?.debug({\n event: \"retry\",\n ...logMessage(\"pokeapi request failed, retrying\"),\n url,\n attempt,\n delayMs,\n ...(status === undefined ? {} : { status }),\n });\n\n await sleep(delayMs, signal);\n};\n","import type { Endpoint } from \"../constants\";\n\n/**\n * Scanned rather than matched with `/\\/+$/`: that pattern backtracks through\n * every slash of a long run that turns out not to end the string, which is\n * quadratic on a URL an untrusted caller supplies. This walks each character\n * once.\n */\nexport const trimTrailingSlash = (url: string): string => {\n let end = url.length;\n\n while (end > 0 && url[end - 1] === \"/\") {\n end -= 1;\n }\n\n return url.slice(0, end);\n};\n\n/** Builds the paginated request path shared by both list methods. */\nexport const listPath = (endpoint: Endpoint, offset: number, limit: number): string => {\n const query = new URLSearchParams({ offset: String(offset), limit: String(limit) });\n\n return `${endpoint}?${query}`;\n};\n\n/**\n * Drops the trailing slash from a request URL, leaving any query string alone.\n *\n * Both call paths must produce one cache key: `Transport.resource` builds\n * `/berry/1`, while the PokéAPI's own links end in a slash.\n *\n * Split at the query rather than matched with a lookahead, for the reason given\n * on {@link trimTrailingSlash}.\n */\nexport const normalizeURL = (url: string): string => {\n const queryAt = url.indexOf(\"?\");\n\n if (queryAt === -1) {\n return trimTrailingSlash(url);\n }\n\n return trimTrailingSlash(url.slice(0, queryAt)) + url.slice(queryAt);\n};\n\n/** A path segment naming an API version, as in `/api/v2/berry/1`. */\nconst API_VERSION_SEGMENT = /^v\\d+$/;\n\n/**\n * Percent-decodes one userinfo component, leaving a component that cannot be\n * decoded as it stands: `URL` accepts sequences `decodeURIComponent` rejects —\n * `us%zzer` parses and then throws — and a credential nobody can decode is still\n * worth sending as written rather than failing the request over.\n */\nconst decodeUserinfo = (component: string): string => {\n try {\n return decodeURIComponent(component);\n } catch {\n return component;\n }\n};\n\n/** Base64-encodes userinfo as RFC 7617 wants it: UTF-8 bytes, percent-decoded. */\nconst toBasicAuth = (username: string, password: string): string => {\n const userinfo = `${decodeUserinfo(username)}:${decodeUserinfo(password)}`;\n const bytes = new TextEncoder().encode(userinfo);\n let latin1 = \"\";\n\n for (const byte of bytes) {\n latin1 += String.fromCodePoint(byte);\n }\n\n return `Basic ${btoa(latin1)}`;\n};\n\n/** A request URL and the `Authorization` header its userinfo became, if any. */\nexport interface CredentiallessURL {\n url: string;\n authorization: string | undefined;\n}\n\n/**\n * Moves any credentials a URL carries into an `Authorization` header.\n *\n * A self-hosted instance behind basic auth is configured as\n * `https://user:secret@host/api/v2`, and that password must not reach the wire\n * as userinfo: `fetch` rejects a credentialed URL outright, and everything\n * downstream of the URL — the log payload, the cache key — would carry it.\n *\n * A URL too malformed to parse cannot carry credentials in the first place, and\n * `fetch` is about to reject it anyway, so it is passed through untouched.\n *\n * The URL that comes back is what everything downstream keys on — the cache\n * entry, the in-flight map, the log line — so two calls to the same host under\n * different credentials share a cache entry and a round trip. That is the trade\n * this exists for: one instance behind one set of credentials. A client per\n * identity needs a `CacheStore` per identity to go with it.\n */\nexport const splitCredentials = (url: string): CredentiallessURL => {\n if (!url.includes(\"@\")) {\n return { url, authorization: undefined };\n }\n\n let parsed: URL;\n\n try {\n parsed = new URL(url);\n } catch {\n return { url, authorization: undefined };\n }\n\n if (!parsed.username && !parsed.password) {\n return { url, authorization: undefined };\n }\n\n const authorization = toBasicAuth(parsed.username, parsed.password);\n\n parsed.username = \"\";\n parsed.password = \"\";\n\n return { url: parsed.toString(), authorization };\n};\n\n/**\n * Reduces an absolute resource URL to the endpoint path to request.\n *\n * When the URL belongs to `baseURL`, the path is simply what follows it.\n * Otherwise — a link from pokeapi.co handed to a client aimed at a self-hosted\n * instance — the path after the API version segment is used, so the resource is\n * re-resolved against the client's own base rather than fetched from elsewhere.\n *\n * The version segment is matched on parsed URL components: a raw-string search\n * also matches a host like `api.v2.example.com`.\n */\nexport const toEndpointPath = (resourceURL: string, baseURL: string): string => {\n const resource = new URL(resourceURL);\n const base = new URL(baseURL);\n const basePath = trimTrailingSlash(base.pathname);\n\n if (\n resource.origin === base.origin &&\n (resource.pathname === basePath || resource.pathname.startsWith(`${basePath}/`))\n ) {\n return `${resource.pathname.slice(basePath.length)}${resource.search}`;\n }\n\n const segments = resource.pathname.split(\"/\");\n const version = segments.findIndex((segment) => API_VERSION_SEGMENT.test(segment));\n\n if (version === -1) {\n throw new TypeError(`Cannot resolve \"${resourceURL}\" against the base URL \"${baseURL}\"`);\n }\n\n return `/${segments.slice(version + 1).join(\"/\")}${resource.search}`;\n};\n","import type {\n ClientOptions,\n ClientStats,\n FetchLike,\n ListFn,\n PaginateOptions,\n RequestScope,\n ResourceLink,\n RetryOptions,\n} from \"../clients/base\";\nimport { type CacheStore, type EtagEntry, EtagStore, MemoryCache } from \"../config/cache\";\nimport { toPokenodeError } from \"../config/errors\";\nimport { type Logger, type LogResponsePayload, logMessage } from \"../config/logger\";\nimport { BASE_URL, type Endpoint } from \"../constants\";\nimport type { APIResource } from \"../models/common/resource\";\nimport { InFlight } from \"./inflight\";\nimport { DEFAULT_PAGE_SIZE, walk as walkPages } from \"./paginate\";\nimport { DEFAULT_CONCURRENCY, mapWithConcurrency } from \"./pool\";\nimport { attemptCount, backoff, isAbort, retryDelay } from \"./retry\";\nimport { listPath, normalizeURL, splitCredentials, toEndpointPath, trimTrailingSlash } from \"./url\";\n\n/** A parsed response body and the status it arrived with. */\ninterface FetchedResource {\n data: unknown;\n status: number;\n /** Whether the body came from an {@link EtagStore} rather than off the wire. */\n revalidated?: boolean;\n}\n\n/** Where a resolution came from, as the response log reports it. */\nconst responseSource = (\n joined: boolean,\n revalidated: boolean | undefined,\n): LogResponsePayload[\"source\"] => {\n if (joined) {\n return \"in-flight\";\n }\n\n return revalidated === true ? \"revalidated\" : \"network\";\n};\n\n/** Resolves the `revalidate` option to the store the client will keep, if any. */\nconst toEtagStore = (revalidate: boolean | EtagStore | undefined): EtagStore | undefined => {\n if (!revalidate) {\n return undefined;\n }\n\n return revalidate === true ? new EtagStore() : revalidate;\n};\n\n/** What a {@link Transport} was configured with, and never changes thereafter. */\ninterface TransportConfig {\n baseURL: string;\n fetch: FetchLike;\n logger: Logger | undefined;\n retry: RetryOptions | undefined;\n}\n\n/**\n * What a {@link Transport} shares with every transport derived from it.\n *\n * Held in one object and passed by reference, so a scoped transport joins the\n * cache, the validators and the requests already on the wire rather than\n * starting its own.\n */\ninterface TransportState {\n cache: CacheStore | undefined;\n etags: EtagStore | undefined;\n /** Requests already on the wire, so concurrent callers share one round trip. */\n inFlight: InFlight<FetchedResource>;\n /** One count per resolution, by where it came from. Shared for the same reason. */\n counts: Record<LogResponsePayload[\"source\"], number>;\n /**\n * Requests that left the process, counted where they are made rather than\n * where they resolve: a resolution retried twice is one `network` and three of\n * these, and only this number is what the API saw.\n */\n roundTrips: { count: number };\n}\n\n/**\n * ## Transport\n * Everything a client does that is not naming an endpoint: requests, caching,\n * retries, revalidation and logging. The rules it works to live beside it, one\n * concern per module — `./url`, `./retry`, `./paginate`, and `./inflight` for\n * the coalescing of concurrent requests.\n *\n * Internal. One transport is built per `MainClient` and handed to all twelve of\n * its section clients, which is what makes a resource fetched through one of\n * them cached — and coalesced — for the rest.\n */\nexport class Transport {\n constructor(\n private readonly config: TransportConfig,\n private readonly state: TransportState,\n private readonly scope: RequestScope = {},\n ) {}\n\n /** Builds a transport, and the state it will share, from public options. */\n static create(clientOptions?: ClientOptions): Transport {\n return new Transport(\n {\n baseURL: trimTrailingSlash(clientOptions?.baseURL ?? BASE_URL.REST),\n fetch: clientOptions?.fetch ?? ((input, init) => globalThis.fetch(input, init)),\n logger: clientOptions?.logger,\n retry: clientOptions?.retry,\n },\n {\n cache:\n clientOptions?.cache === false ? undefined : (clientOptions?.cache ?? new MemoryCache()),\n etags: toEtagStore(clientOptions?.revalidate),\n inFlight: new InFlight(),\n counts: { network: 0, cache: 0, \"in-flight\": 0, revalidated: 0 },\n roundTrips: { count: 0 },\n },\n );\n }\n\n /** The counts so far, as a snapshot: the state behind them keeps moving. */\n get stats(): ClientStats {\n const { network, cache, revalidated } = this.state.counts;\n\n return {\n network,\n cache,\n inFlight: this.state.counts[\"in-flight\"],\n revalidated,\n roundTrips: this.state.roundTrips.count,\n };\n }\n\n /** The store backing this transport, or `undefined` when caching is disabled. */\n get cache(): CacheStore | undefined {\n return this.state.cache;\n }\n\n /**\n * Derives a transport whose requests carry a signal, a timeout, or both.\n *\n * The derived transport shares this one's state, so a scoped call still joins\n * an identical unscoped one instead of repeating it.\n */\n with(scope: RequestScope): Transport {\n return new Transport(this.config, this.state, { ...this.scope, ...scope });\n }\n\n /**\n * Drops every cached response, and the validators held for them: an\n * {@link EtagStore} keeps the bodies it learned, so leaving it would answer\n * the next request with the very body that was just dropped.\n *\n * A {@link CacheStore} that does not implement `clear` is left alone.\n */\n async clear(): Promise<void> {\n await this.state.cache?.clear?.();\n this.state.etags?.clear();\n }\n\n /**\n * Retrieves a single resource by its endpoint and identifier.\n *\n * Every segment is percent-encoded. A name reaches here as whatever the caller\n * passed — `getBerryByName(req.query.name)` is the shape that call takes — and\n * unencoded a `?` in it becomes a query, a `/` another endpoint, and a `#` a\n * fragment that is dropped before the wire but not before the cache key. A\n * path below the endpoint is given as separate segments for that reason.\n */\n async resource<T>(endpoint: Endpoint, ...segments: (string | number)[]): Promise<T> {\n const path = segments.map((segment) => encodeURIComponent(segment)).join(\"/\");\n\n return this.request<T>(path === \"\" ? endpoint : `${endpoint}/${path}`);\n }\n\n /** Retrieves a resource by its URL, or by a link taken from another response. */\n async byURL<T>(resource: ResourceLink<T>, baseURL = this.config.baseURL): Promise<T> {\n const url = typeof resource === \"string\" ? resource : resource.url;\n\n return this.request<T>(toEndpointPath(url, baseURL), baseURL);\n }\n\n /** Retrieves one page of a list endpoint. */\n async list<T>(endpoint: Endpoint, offset = 0, limit = DEFAULT_PAGE_SIZE): Promise<T> {\n return this.request<T>(listPath(endpoint, offset, limit));\n }\n\n /** Fetches what several links point at, in the order they were given. */\n async resolveAll<T>(\n resources: readonly ResourceLink<T>[],\n concurrency = DEFAULT_CONCURRENCY,\n ): Promise<T[]> {\n return mapWithConcurrency(resources, concurrency, (resource) => this.byURL<T>(resource));\n }\n\n /** Walks every page of a list endpoint, yielding one entry at a time. */\n walk<T>(\n list: ListFn<APIResource<T>>,\n options?: PaginateOptions,\n ): AsyncGenerator<APIResource<T> | T> {\n return walkPages(list, (link) => this.byURL(link), options);\n }\n\n /**\n * Resolves a resource through the cache, then through any identical request\n * already in flight, and only then over the network.\n *\n * The URL is joined by concatenation: `new URL(path, base)` would discard the\n * base's own `/api/v2` path.\n */\n private async request<T>(path: string, baseURL = this.config.baseURL): Promise<T> {\n const rooted = path.startsWith(\"/\") ? path : `/${path}`;\n\n // Credentials leave the URL before anything else sees it: `fetch` rejects a\n // credentialed URL, and the cache key and log payload are built from this.\n const { url, authorization } = splitCredentials(\n normalizeURL(`${trimTrailingSlash(baseURL)}${rooted}`),\n );\n\n const startedAt = performance.now();\n\n this.config.logger?.debug({\n event: \"request\",\n ...logMessage(\"pokeapi request\"),\n method: \"GET\",\n url,\n });\n\n const signal = this.requestSignal();\n\n try {\n // Checked before anything else happens, and before the cache is consulted:\n // a call made through a scope that has already aborted must not reach the\n // network, and must not depend on what happens to be cached either.\n if (signal?.aborted) {\n throw signal.reason;\n }\n\n const cached = await this.state.cache?.get(url);\n\n if (cached !== undefined) {\n // A hit is timed like any other resolution: the number is small, but a\n // store on the far side of a network is not guaranteed to make it so.\n this.recordResponse(url, 200, \"cache\", startedAt);\n return cached as T;\n }\n\n // Every caller reports its own outcome, including one that only joined a\n // request someone else started: a `request` event with no `response` to\n // close it would make concurrent traffic unreadable. `source` is what keeps\n // the count of round trips honest when several callers share one.\n const { value, joined } = await this.state.inFlight.share(url, signal, (requestSignal) =>\n this.fetchResource(url, authorization, requestSignal),\n );\n\n this.recordResponse(url, value.status, responseSource(joined, value.revalidated), startedAt);\n\n return value.data as T;\n } catch (error) {\n // A cancelled request is not a failed one, by the same rule that stops the\n // retry loop from attempting it again.\n if (isAbort(error, signal)) {\n this.config.logger?.debug({\n event: \"cancelled\",\n ...logMessage(\"pokeapi request cancelled\"),\n url,\n reason: error,\n durationMs: performance.now() - startedAt,\n });\n throw error;\n }\n\n this.config.logger?.error({\n event: \"error\",\n ...logMessage(\"pokeapi request failed\"),\n url,\n err: error,\n error,\n });\n throw error;\n }\n }\n\n /**\n * The signal this scope puts on a request, or none when it has nothing to\n * cancel with. A timeout is created per request, not per scope: a scope is\n * derived once and used many times.\n */\n private requestSignal(): AbortSignal | undefined {\n const { signal, timeout } = this.scope;\n\n if (timeout === undefined) {\n return signal;\n }\n\n const expiry = AbortSignal.timeout(timeout);\n\n return signal ? AbortSignal.any([signal, expiry]) : expiry;\n }\n\n private async fetchResource(\n url: string,\n authorization: string | undefined,\n signal: AbortSignal | undefined,\n ): Promise<FetchedResource> {\n // Read once, before any attempt: an entry evicted while the request is in\n // flight must not turn a 304 into a response with no body to go with it.\n const known = this.state.etags?.get(url);\n const headers = {\n Accept: \"application/json\",\n ...(authorization === undefined ? {} : { Authorization: authorization }),\n ...(known === undefined ? {} : { \"If-None-Match\": known.etag }),\n };\n const init = signal ? { headers, signal } : { headers };\n const { retry, logger } = this.config;\n const attempts = attemptCount(retry);\n\n for (let attempt = 1; ; attempt += 1) {\n const isLast = attempt >= attempts;\n let response: Response;\n\n try {\n // Counted before the call rather than after: an attempt that throws\n // still left the process, and a retry loop nobody can see is what makes\n // a client cost more than its caller thinks.\n this.state.roundTrips.count += 1;\n response = await this.config.fetch(url, init);\n } catch (error) {\n // A cancelled request is not a failed one, so no attempt follows it.\n if (isLast || isAbort(error, signal)) {\n throw error;\n }\n\n await backoff({\n url,\n attempt,\n status: undefined,\n retryAfter: undefined,\n signal,\n retry,\n logger,\n });\n continue;\n }\n\n const resolved = await this.resolveResponse(url, response, known);\n\n if (resolved !== undefined) {\n return resolved;\n }\n\n const retryAfter = await retryDelay(response, isLast, retry);\n\n // The body is going nowhere, and an undrained one holds its connection.\n // Not awaited: an intercepted response may never settle the cancellation,\n // and nothing here depends on it having finished.\n response.body?.cancel().catch(() => {});\n await backoff({ url, attempt, status: response.status, retryAfter, signal, retry, logger });\n }\n }\n\n /**\n * The resource a response carries, or nothing when it carries none and another\n * attempt is the question.\n */\n private async resolveResponse(\n url: string,\n response: Response,\n known: EtagEntry | undefined,\n ): Promise<FetchedResource | undefined> {\n // Checked before `ok`, which a 304 is not: nothing changed, so the body\n // that was sent with the validator is still the answer.\n if (response.status === 304) {\n if (known === undefined) {\n // Nothing here asked for it, so nothing here can satisfy it — an\n // intermediary added a validator of its own. Reported on its own terms\n // rather than left to fall through as an unexplained failed status.\n throw await toPokenodeError(\n response,\n `Request to ${response.url} was answered 304, but this client holds no response to reuse`,\n );\n }\n\n // RFC 9110 lets a 304 carry a validator of its own, and a server that\n // re-encodes an unchanged body rotates it. Keeping the one that was sent\n // would spend the next revalidation on a full body.\n const refreshed = response.headers.get(\"ETag\");\n\n if (refreshed !== null && refreshed !== known.etag) {\n this.state.etags?.set(url, { etag: refreshed, value: known.value });\n }\n\n await this.state.cache?.set(url, known.value);\n\n return { data: known.value, status: response.status, revalidated: true };\n }\n\n if (!response.ok) {\n return undefined;\n }\n\n const data: unknown = await response.json();\n const etag = response.headers.get(\"ETag\");\n\n if (etag !== null) {\n this.state.etags?.set(url, { etag, value: data });\n }\n\n await this.state.cache?.set(url, data);\n\n return { data, status: response.status };\n }\n\n /**\n * The one place a resolution is accounted for, however it was resolved — which\n * is what keeps {@link Transport.stats} and the response log saying the same\n * thing about the same request.\n */\n private recordResponse(\n url: string,\n status: number,\n source: LogResponsePayload[\"source\"],\n startedAt: number,\n ): void {\n this.state.counts[source] += 1;\n\n this.config.logger?.debug({\n event: \"response\",\n ...logMessage(\"pokeapi response\"),\n url,\n status,\n source,\n durationMs: performance.now() - startedAt,\n });\n }\n}\n","import type { CacheStore, EtagStore } from \"../config/cache\";\nimport type { Logger } from \"../config/logger\";\nimport type { Endpoint } from \"../constants\";\nimport { Transport } from \"../internal/transport\";\nimport type {\n APIResource,\n APIResourceList,\n NamedAPIResource,\n NamedAPIResourceList,\n} from \"../models/common/resource\";\n\n/**\n * ## Fetch Like\n * A `fetch` implementation taking a string URL, as every client call does.\n */\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\n/**\n * ## Resource Link\n * Something naming a single resource: a link taken from a response, or its URL\n * as a bare string.\n *\n * A link carries what it points at, so passing one infers `T`; a string does\n * not, and needs `T` named.\n */\nexport type ResourceLink<T> = string | NamedAPIResource<T> | APIResource<T>;\n\n/**\n * ## Retry Options\n * When a failed request is worth attempting again.\n *\n * Retrying is off unless this is given — a client that quietly triples its own\n * traffic is not something to opt out of after the fact.\n */\nexport interface RetryOptions {\n /** Attempts in total, the first one included. Defaults to 3. */\n attempts?: number;\n /** Statuses worth another attempt. Defaults to 429, 500, 502, 503 and 504. */\n statuses?: number[];\n /** The first wait, in milliseconds, doubling from there. Defaults to 300. */\n initialDelay?: number;\n /** The longest this client will ever wait between attempts. Defaults to 5000. */\n maxDelay?: number;\n}\n\n/**\n * ## Request Scope\n * Cancellation applied to every request a client makes.\n *\n * Passed to {@link ClientFacade.with}, not to the constructor: a signal belongs\n * to one unit of work, while a client outlives many, and a client holding a\n * signal for its whole life is dead the first time that signal aborts.\n */\nexport interface RequestScope {\n /** Aborts the requests made through this scope. */\n signal?: AbortSignal;\n /** How long a request may take, in milliseconds, before it is aborted. */\n timeout?: number;\n}\n\n/**\n * ## Client Options\n * Optional configuration accepted by every client.\n */\nexport interface ClientOptions {\n /**\n * Where the request lifecycle is reported. Leave empty to log nothing, or pass\n * {@link consoleLogger} to write it to the console.\n */\n logger?: Logger;\n /**\n * Response cache. Leave empty for an in-memory {@link MemoryCache}, pass `false`\n * to disable caching, or supply your own {@link CacheStore}.\n */\n cache?: CacheStore | false;\n /** Location of the PokéAPI. Leave empty to use the official PokéAPI instance. */\n baseURL?: string;\n /**\n * Custom `fetch` implementation, for proxies, retries, cancellation or\n * instrumentation. Defaults to the global `fetch`.\n *\n * Requests carry no timeout of their own: derive a scoped client with\n * {@link ClientFacade.with} if you want one.\n */\n fetch?: FetchLike;\n /**\n * When to attempt a failed request again. Leave empty to attempt each request\n * exactly once.\n */\n retry?: RetryOptions;\n /**\n * Ask the PokéAPI whether a response has changed, rather than downloading it\n * again, once the {@link CacheStore} entry for it has expired.\n *\n * Pass `true` for a default {@link EtagStore}, or one of your own to size it.\n * Leave empty and every expired entry is refetched in full.\n */\n revalidate?: boolean | EtagStore;\n}\n\n/**\n * ## Client Stats\n * How many resolutions came from where, since the client was built.\n *\n * One count per `source` a {@link LogResponsePayload} reports, which is the only\n * thing that tells a cache hit from a revalidation from a real round trip once\n * the promise has settled. A failed request is counted by neither: it resolved\n * nothing, and it is the logger's `error` event that has it.\n */\nexport interface ClientStats {\n /** Responses downloaded in full. */\n network: number;\n /** Responses answered from the {@link CacheStore}, with no request made. */\n cache: number;\n /** Callers that joined a request already on the wire rather than repeating it. */\n inFlight: number;\n /** Responses the PokéAPI answered `304` for, served from the {@link EtagStore}. */\n revalidated: number;\n /**\n * Requests that left the process — what the PokéAPI actually saw.\n *\n * Not `network + revalidated`. A revalidation is a round trip that saved a\n * body rather than a request that never happened, so it is in here; and a\n * resolution the `retry` option attempted three times is one `network` and\n * three of these. The attempts are the half a caller cannot see, and they are\n * the half that shows up in someone else's rate limit.\n */\n roundTrips: number;\n}\n\n/**\n * ## List Page\n * The part of a resource list a walk needs: how much there is, and this page of\n * it. Both {@link NamedAPIResourceList} and {@link APIResourceList} qualify.\n */\nexport interface ListPage<L> {\n count: number;\n results: L[];\n}\n\n/**\n * ## List Fn\n * A list method, called with the offset and the limit of the page to fetch.\n */\nexport type ListFn<L> = (offset: number, limit: number) => Promise<ListPage<L>>;\n\n/**\n * ## List Method\n * The shape every `list*` method on a section client has.\n */\nexport type ListMethod = (\n offset?: number,\n limit?: number,\n) => Promise<ListPage<APIResource<unknown>>>;\n\n/**\n * ## List Method Name\n * The names of `C`'s own list methods, and nothing else — so naming one to\n * {@link BaseClient.paginate} is checked and completed by the compiler.\n */\nexport type ListMethodName<C> = {\n [K in keyof C]: C[K] extends ListMethod ? K : never;\n}[keyof C];\n\n/** What a list method's page is made of. */\nexport type Listed<F> = F extends (offset?: number, limit?: number) => Promise<ListPage<infer L>>\n ? L\n : never;\n\n/** What a listed link resolves to. */\nexport type Resolves<L> = L extends APIResource<infer T> ? T : never;\n\n/**\n * ## Paginate Options\n * How {@link BaseClient.paginate} walks a list endpoint.\n */\nexport interface PaginateOptions {\n /** Entries fetched per request. Defaults to 20. */\n pageSize?: number;\n /** Fetch each link and yield the resource instead. Defaults to `false`. */\n resolve?: boolean;\n /** Links resolved at a time, when `resolve` is set. Defaults to 4. */\n concurrency?: number;\n}\n\n/**\n * ## Resolve Options\n * How {@link ClientFacade.resolveAll} fetches the links it was given.\n */\nexport interface ResolveOptions {\n /** Links fetched at a time. Defaults to 4. */\n concurrency?: number;\n}\n\n/**\n * ## Client Facade\n * What every client is, underneath: something that owns a transport and talks\n * to it. Holds the members {@link BaseClient} and {@link MainClient} would\n * otherwise each declare — the cache, the scope, and following a link.\n *\n * The transport is a `#private` field rather than a `protected` one so that\n * nothing about it reaches the published types: a `protected` member keeps its\n * type in the emitted `.d.ts`, which would put the whole internal transport\n * surface in front of consumers who cannot name it.\n */\nexport abstract class ClientFacade {\n readonly #transport: Transport;\n\n constructor(options?: ClientOptions);\n /** @internal Shares the transport a client already holds. */\n constructor(source?: ClientOptions | Transport);\n constructor(source?: ClientOptions | Transport) {\n this.#transport = source instanceof Transport ? source : Transport.create(source);\n }\n\n /** The store backing this client, or `undefined` when caching is disabled. */\n public get cache(): CacheStore | undefined {\n return this.#transport.cache;\n }\n\n /**\n * How many resolutions came from where.\n *\n * ```ts\n * await api.pokemon.getPokemonByName('luxray');\n * await api.pokemon.getPokemonByName('luxray');\n *\n * api.stats; // { network: 1, cache: 1, inFlight: 0, revalidated: 0, roundTrips: 1 }\n * ```\n *\n * The counts are the transport's, so they cover every section of a\n * {@link MainClient} and every client derived with {@link ClientFacade.with} —\n * the same sharing that makes one cache serve all of them.\n *\n * A snapshot, read at the moment it is asked for. Keeping one to compare\n * against later means keeping the object, not the client.\n */\n public get stats(): ClientStats {\n return this.#transport.stats;\n }\n\n /**\n * What has been counted since `snapshot` was taken.\n *\n * ```ts\n * const before = api.stats;\n * await renderTeam();\n *\n * api.statsSince(before).roundTrips; // what that render cost\n * ```\n *\n * There is no way to reset the counts, and this is why: the transport behind\n * them is shared by every section of a {@link MainClient} and by every client\n * derived with {@link ClientFacade.with}, so zeroing it for one measurement\n * zeroes it for whatever else is measuring. Subtraction is the same answer\n * without the shared mutation.\n */\n public statsSince(snapshot: ClientStats): ClientStats {\n const now = this.#transport.stats;\n\n return {\n network: now.network - snapshot.network,\n cache: now.cache - snapshot.cache,\n inFlight: now.inFlight - snapshot.inFlight,\n revalidated: now.revalidated - snapshot.revalidated,\n roundTrips: now.roundTrips - snapshot.roundTrips,\n };\n }\n\n /**\n * Derives a client whose requests carry a signal, a timeout, or both.\n *\n * The clone shares this client's transport — its cache, its validators and the\n * requests already on the wire — so a scoped call still joins an identical\n * unscoped one instead of repeating it. Cloning is cheap, but not free: derive\n * one per unit of work — a request handler, a job — rather than one per call.\n *\n * ```ts\n * const scoped = api.with({ signal: request.signal, timeout: 2_000 });\n * ```\n */\n public with(scope: RequestScope): this {\n // Rebuilt through the constructor rather than copied, so that whatever a\n // subclass sets up is initialised instead of skipped — the twelve sections\n // `MainClient` builds, for one. Every constructor down here takes the same\n // `ClientOptions | Transport`, which is what makes the cast hold.\n const Client = this.constructor as new (transport: Transport) => this;\n\n return new Client(this.#transport.with(scope));\n }\n\n /**\n * Drops every cached response, and any `ETag` learned for one — otherwise the\n * next request revalidates and is answered with the body just dropped.\n *\n * A {@link CacheStore} that does not implement `clear` is left alone.\n *\n * The store is the transport's, so a client sharing one with others clears\n * theirs too.\n */\n public async clearCache(): Promise<void> {\n await this.#transport.clear();\n }\n\n /**\n * Fetches what a link points at, through this client's cache and scope.\n *\n * A link carries what it points at, so the result is typed without saying so:\n *\n * ```ts\n * const pokemon = await api.getPokemonByName('luxray');\n * const species = await api.resolve(pokemon.species);\n * // ^? PokemonSpecies\n * ```\n *\n * A link names a resource, not a section, so any client resolves any link.\n *\n * @throws {TypeError} If the URL is not valid, or names no PokéAPI endpoint.\n */\n public async resolve<T>(resource: ResourceLink<T>): Promise<T> {\n return this.#transport.byURL<T>(resource);\n }\n\n /**\n * Fetches what several links point at, in the order they were given.\n *\n * At most `concurrency` requests run at a time — four by default, because the\n * PokéAPI's fair-use policy asks clients not to flood it. The first failure\n * rejects, and no further link is fetched.\n *\n * ```ts\n * const types = await api.resolveAll(pokemon.types.map((slot) => slot.type));\n * // ^? Type[]\n * ```\n */\n public async resolveAll<T>(\n resources: readonly ResourceLink<T>[],\n options?: ResolveOptions,\n ): Promise<T[]> {\n return this.#transport.resolveAll<T>(resources, options?.concurrency);\n }\n\n /**\n * Retrieves a single resource from the PokéAPI by its endpoint and identifier.\n *\n * @param segments - The identifier of the resource, followed by any path below\n * it. Each is percent-encoded, so pass `id, 'encounters'` rather than\n * `` `${id}/encounters` ``. Omit them to address the endpoint itself.\n */\n protected async getResource<T>(endpoint: Endpoint, ...segments: (string | number)[]): Promise<T> {\n return this.#transport.resource<T>(endpoint, ...segments);\n }\n\n /**\n * Retrieves a resource by its URL, or by a link taken from another response.\n *\n * A link knows what it points at, so passing one infers `T`; a bare string\n * does not, and needs `T` named.\n *\n * @throws {TypeError} If the URL is not valid, or names no endpoint under `baseURL`.\n */\n protected async getResourceByURL<T>(resource: ResourceLink<T>, baseURL?: string): Promise<T> {\n return this.#transport.byURL<T>(resource, baseURL);\n }\n\n /**\n * Retrieves a list of resources from the PokéAPI with pagination support.\n *\n * @template T - What the listed links resolve to.\n */\n protected async getListResource<T = unknown>(\n endpoint: Endpoint,\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<T>> {\n return this.#transport.list<NamedAPIResourceList<T>>(endpoint, offset, limit);\n }\n\n /**\n * Retrieves a list of resources that have no name to list, with pagination support.\n *\n * @template T - What the listed links resolve to.\n */\n protected async getUnnamedListResource<T = unknown>(\n endpoint: Endpoint,\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<T>> {\n return this.#transport.list<APIResourceList<T>>(endpoint, offset, limit);\n }\n\n /**\n * Walks every page of a list, yielding one entry at a time. The bridge\n * {@link BaseClient.paginate} reaches the transport through, so that no\n * signature here has to name one.\n */\n protected walk<T>(\n list: ListFn<APIResource<T>>,\n options?: PaginateOptions,\n ): AsyncGenerator<APIResource<T> | T> {\n return this.#transport.walk(list, options);\n }\n}\n\n/**\n * ## Base Client\n * Base class for every section client. Names endpoints; the transport behind\n * {@link ClientFacade} does everything else — requests, caching, coalescing,\n * retries and logs.\n *\n * A {@link MainClient} builds one transport and hands it to all twelve of its\n * section clients, which is what makes them share a cache and a round trip.\n */\nexport class BaseClient extends ClientFacade {\n /**\n * Walks every page of a list endpoint, yielding one entry at a time.\n *\n * Name the list method to walk; the offset and the limit are this method's to\n * manage.\n *\n * ```ts\n * for await (const berry of api.berry.paginate('listBerries')) {\n * console.log(berry.name);\n * }\n * ```\n *\n * With `resolve`, each link is fetched and the resource is yielded instead of\n * the link. Requests are capped at `concurrency` at a time — the default is\n * deliberately low, because walking a section is exactly the traffic the\n * PokéAPI's fair-use policy asks clients to keep gentle.\n *\n * ```ts\n * for await (const berry of api.berry.paginate('listBerries', { resolve: true })) {\n * console.log(berry.growth_time);\n * }\n * ```\n *\n * A function is accepted too, for a list this client does not carry — a page\n * of a foreign endpoint, or one narrowed before the walk sees it.\n *\n * ```ts\n * api.berry.paginate((offset, limit) => api.berry.listBerries(offset, limit));\n * ```\n */\n public paginate<K extends ListMethodName<this>>(\n list: K,\n options?: PaginateOptions & { resolve?: false },\n ): AsyncGenerator<Listed<this[K]>>;\n public paginate<K extends ListMethodName<this>>(\n list: K,\n options: PaginateOptions & { resolve: true },\n ): AsyncGenerator<Resolves<Listed<this[K]>>>;\n public paginate<L extends APIResource<unknown>>(\n list: ListFn<L>,\n options?: PaginateOptions & { resolve?: false },\n ): AsyncGenerator<L>;\n public paginate<T>(\n list: ListFn<APIResource<T>>,\n options: PaginateOptions & { resolve: true },\n ): AsyncGenerator<T>;\n public paginate<T>(\n list: ListFn<APIResource<T>> | ListMethodName<this>,\n options?: PaginateOptions,\n ): AsyncGenerator<APIResource<T> | T> {\n // A named method is bound here rather than by the caller: reaching it\n // through `this` is the whole point of naming it, and `this` is what\n // carries the scope a derived client was given.\n const listPage =\n typeof list === \"function\"\n ? list\n : (offset: number, limit: number) => (this[list] as ListFn<APIResource<T>>)(offset, limit);\n\n return this.walk(listPage, options);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Berry, BerryFirmness, BerryFlavor, NamedAPIResourceList } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Berry Client\n *\n * Client used to access the Berry Endpoints:\n *\n * - [Berries](https://pokeapi.co/docs/v2#berries)\n * - [Berry Firmnesses](https://pokeapi.co/docs/v2#berry-firmnesses)\n * - [Berry Flavors](https://pokeapi.co/docs/v2#berry-flavors)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#berries-section)\n */\nexport class BerryClient extends BaseClient {\n /** Get a Berry by its name. */\n public async getBerryByName(name: string): Promise<Berry> {\n return this.getResource(ENDPOINTS.BERRY, name);\n }\n\n /** Get a Berry by its ID. */\n public async getBerryById(id: number): Promise<Berry> {\n return this.getResource(ENDPOINTS.BERRY, id);\n }\n\n /** Get a Berry Firmness by its ID. */\n public async getBerryFirmnessById(id: number): Promise<BerryFirmness> {\n return this.getResource(ENDPOINTS.BERRY_FIRMNESS, id);\n }\n\n /** Get a Berry Firmness by its name. */\n public async getBerryFirmnessByName(name: string): Promise<BerryFirmness> {\n return this.getResource(ENDPOINTS.BERRY_FIRMNESS, name);\n }\n\n /** Get a Berry Flavor by its ID. */\n public async getBerryFlavorById(id: number): Promise<BerryFlavor> {\n return this.getResource(ENDPOINTS.BERRY_FLAVOR, id);\n }\n\n /** Get a Berry Flavor by its name. */\n public async getBerryFlavorByName(name: string): Promise<BerryFlavor> {\n return this.getResource(ENDPOINTS.BERRY_FLAVOR, name);\n }\n\n /** List Berries. Page defaults to 20 entries from offset 0. */\n public async listBerries(offset?: number, limit?: number): Promise<NamedAPIResourceList<Berry>> {\n return this.getListResource<Berry>(ENDPOINTS.BERRY, offset, limit);\n }\n\n /** List Berry Firmnesses. Page defaults to 20 entries from offset 0. */\n public async listBerryFirmnesses(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<BerryFirmness>> {\n return this.getListResource<BerryFirmness>(ENDPOINTS.BERRY_FIRMNESS, offset, limit);\n }\n\n /** List Berry Flavors. Page defaults to 20 entries from offset 0. */\n public async listBerryFlavors(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<BerryFlavor>> {\n return this.getListResource<BerryFlavor>(ENDPOINTS.BERRY_FLAVOR, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n APIResourceList,\n ContestEffect,\n ContestType,\n NamedAPIResourceList,\n SuperContestEffect,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Contest Client\n *\n * Client used to access the Contest Endpoints:\n *\n * - [Contest Types](https://pokeapi.co/docs/v2#contest-types)\n * - [Contest Effects](https://pokeapi.co/docs/v2#contest-effects)\n * - [Super Contest Effects](https://pokeapi.co/docs/v2#super-contest-effects)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#contests-section)\n */\nexport class ContestClient extends BaseClient {\n /** Get a Contest Type by its name. */\n public async getContestTypeByName(name: string): Promise<ContestType> {\n return this.getResource(ENDPOINTS.CONTEST_TYPE, name);\n }\n\n /** Get a Contest Type by its ID. */\n public async getContestTypeById(id: number): Promise<ContestType> {\n return this.getResource(ENDPOINTS.CONTEST_TYPE, id);\n }\n\n /** Get a Contest Effect by its ID. */\n public async getContestEffectById(id: number): Promise<ContestEffect> {\n return this.getResource(ENDPOINTS.CONTEST_EFFECT, id);\n }\n\n /** Get a Super Contest Effect by its ID. */\n public async getSuperContestEffectById(id: number): Promise<SuperContestEffect> {\n return this.getResource(ENDPOINTS.SUPER_CONTEST_EFFECT, id);\n }\n\n /** List Contest Types. Page defaults to 20 entries from offset 0. */\n public async listContestTypes(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ContestType>> {\n return this.getListResource<ContestType>(ENDPOINTS.CONTEST_TYPE, offset, limit);\n }\n\n /** List Contest Effects. Page defaults to 20 entries from offset 0. */\n public async listContestEffects(\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<ContestEffect>> {\n return this.getUnnamedListResource<ContestEffect>(ENDPOINTS.CONTEST_EFFECT, offset, limit);\n }\n\n /** List Super Contest Effects. Page defaults to 20 entries from offset 0. */\n public async listSuperContestEffects(\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<SuperContestEffect>> {\n return this.getUnnamedListResource<SuperContestEffect>(\n ENDPOINTS.SUPER_CONTEST_EFFECT,\n offset,\n limit,\n );\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Currency, NamedAPIResourceList } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Currency Client\n *\n * Client used to access the Currency Endpoints:\n *\n * - [Currencies](https://pokeapi.co/docs/v2#currencies)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#currencies-section)\n */\nexport class CurrencyClient extends BaseClient {\n /** Get a Currency by its name. */\n public async getCurrencyByName(name: string): Promise<Currency> {\n return this.getResource(ENDPOINTS.CURRENCY, name);\n }\n\n /** Get a Currency by its ID. */\n public async getCurrencyById(id: number): Promise<Currency> {\n return this.getResource(ENDPOINTS.CURRENCY, id);\n }\n\n /** List Currencies. Page defaults to 20 entries from offset 0. */\n public async listCurrencies(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Currency>> {\n return this.getListResource<Currency>(ENDPOINTS.CURRENCY, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n EncounterCondition,\n EncounterConditionValue,\n EncounterMethod,\n NamedAPIResourceList,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Encounter Client\n *\n * Client used to access the Encounter Endpoints:\n *\n * - [Encounter Methods](https://pokeapi.co/docs/v2#encounter-methods)\n * - [Encounter Conditions](https://pokeapi.co/docs/v2#encounter-conditions)\n * - [Encounter Condition Values](https://pokeapi.co/docs/v2#encounter-condition-values)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#encounters-section)\n */\nexport class EncounterClient extends BaseClient {\n /** Get an Encounter Method by its name. */\n public async getEncounterMethodByName(name: string): Promise<EncounterMethod> {\n return this.getResource<EncounterMethod>(ENDPOINTS.ENCOUNTER_METHOD, name);\n }\n\n /** Get an Encounter Method by its ID. */\n public async getEncounterMethodById(id: number): Promise<EncounterMethod> {\n return this.getResource<EncounterMethod>(ENDPOINTS.ENCOUNTER_METHOD, id);\n }\n\n /** Get an Encounter Condition by its ID. */\n public async getEncounterConditionById(id: number): Promise<EncounterCondition> {\n return this.getResource<EncounterCondition>(ENDPOINTS.ENCOUNTER_CONDITION, id);\n }\n\n /** Get an Encounter Condition by its name. */\n public async getEncounterConditionByName(name: string): Promise<EncounterCondition> {\n return this.getResource<EncounterCondition>(ENDPOINTS.ENCOUNTER_CONDITION, name);\n }\n\n /** Get an Encounter Condition Value by its name. */\n public async getEncounterConditionValueByName(name: string): Promise<EncounterConditionValue> {\n return this.getResource<EncounterConditionValue>(ENDPOINTS.ENCOUNTER_CONDITION_VALUE, name);\n }\n\n /** Get an Encounter Condition Value by its ID. */\n public async getEncounterConditionValueById(id: number): Promise<EncounterConditionValue> {\n return this.getResource<EncounterConditionValue>(ENDPOINTS.ENCOUNTER_CONDITION_VALUE, id);\n }\n\n /** List Encounter Methods. Page defaults to 20 entries from offset 0. */\n public async listEncounterMethods(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EncounterMethod>> {\n return this.getListResource<EncounterMethod>(ENDPOINTS.ENCOUNTER_METHOD, offset, limit);\n }\n\n /** List Encounter Conditions. Page defaults to 20 entries from offset 0. */\n public async listEncounterConditions(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EncounterCondition>> {\n return this.getListResource<EncounterCondition>(ENDPOINTS.ENCOUNTER_CONDITION, offset, limit);\n }\n\n /** List Encounter Condition Values. Page defaults to 20 entries from offset 0. */\n public async listEncounterConditionValues(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EncounterConditionValue>> {\n return this.getListResource<EncounterConditionValue>(\n ENDPOINTS.ENCOUNTER_CONDITION_VALUE,\n offset,\n limit,\n );\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n APIResourceList,\n EvolutionChain,\n EvolutionTrigger,\n NamedAPIResourceList,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Evolution Client\n *\n * Client used to access the Evolution Endpoints:\n *\n * - [Evolution Chains](https://pokeapi.co/docs/v2#evolution-chains)\n * - [Evolution Triggers](https://pokeapi.co/docs/v2#evolution-triggers)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#evolution-section)\n */\nexport class EvolutionClient extends BaseClient {\n /** Get an Evolution Chain by its ID. */\n public async getEvolutionChainById(id: number): Promise<EvolutionChain> {\n return this.getResource(ENDPOINTS.EVOLUTION_CHAIN, id);\n }\n\n /** Get an Evolution Trigger by its ID. */\n public async getEvolutionTriggerById(id: number): Promise<EvolutionTrigger> {\n return this.getResource(ENDPOINTS.EVOLUTION_TRIGGER, id);\n }\n\n /** Get an Evolution Trigger by its name. */\n public async getEvolutionTriggerByName(name: string): Promise<EvolutionTrigger> {\n return this.getResource(ENDPOINTS.EVOLUTION_TRIGGER, name);\n }\n\n /** List Evolution Chains. Page defaults to 20 entries from offset 0. */\n public async listEvolutionChains(\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<EvolutionChain>> {\n return this.getUnnamedListResource<EvolutionChain>(ENDPOINTS.EVOLUTION_CHAIN, offset, limit);\n }\n\n /** List Evolution Triggers. Page defaults to 20 entries from offset 0. */\n public async listEvolutionTriggers(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EvolutionTrigger>> {\n return this.getListResource<EvolutionTrigger>(ENDPOINTS.EVOLUTION_TRIGGER, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Generation, NamedAPIResourceList, Pokedex, Version, VersionGroup } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Game Client\n *\n * Client used to access the Game Endpoints:\n *\n * - [Generations](https://pokeapi.co/docs/v2#generations)\n * - [Pokédexes](https://pokeapi.co/docs/v2#pokedexes)\n * - [Versions](https://pokeapi.co/docs/v2#version)\n * - [Version Groups](https://pokeapi.co/docs/v2#version-groups)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#games-section)\n */\nexport class GameClient extends BaseClient {\n /** Get a Generation by its name. */\n public async getGenerationByName(name: string): Promise<Generation> {\n return this.getResource(ENDPOINTS.GENERATION, name);\n }\n\n /** Get a Generation by its ID. */\n public async getGenerationById(id: number): Promise<Generation> {\n return this.getResource(ENDPOINTS.GENERATION, id);\n }\n\n /** Get a Pokédex by its name. */\n public async getPokedexByName(name: string): Promise<Pokedex> {\n return this.getResource(ENDPOINTS.POKEDEX, name);\n }\n\n /** Get a Pokédex by its ID. */\n public async getPokedexById(id: number): Promise<Pokedex> {\n return this.getResource(ENDPOINTS.POKEDEX, id);\n }\n\n /** Get a Version by its name. */\n public async getVersionByName(name: string): Promise<Version> {\n return this.getResource(ENDPOINTS.VERSION, name);\n }\n\n /** Get a Version by its ID. */\n public async getVersionById(id: number): Promise<Version> {\n return this.getResource(ENDPOINTS.VERSION, id);\n }\n\n /** Get a Version Group by its name. */\n public async getVersionGroupByName(name: string): Promise<VersionGroup> {\n return this.getResource(ENDPOINTS.VERSION_GROUP, name);\n }\n\n /** Get a Version Group by its ID. */\n public async getVersionGroupById(id: number): Promise<VersionGroup> {\n return this.getResource(ENDPOINTS.VERSION_GROUP, id);\n }\n\n /** List Generations. Page defaults to 20 entries from offset 0. */\n public async listGenerations(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Generation>> {\n return this.getListResource<Generation>(ENDPOINTS.GENERATION, offset, limit);\n }\n\n /** List Pokédexes. Page defaults to 20 entries from offset 0. */\n public async listPokedexes(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Pokedex>> {\n return this.getListResource<Pokedex>(ENDPOINTS.POKEDEX, offset, limit);\n }\n\n /** List Versions. Page defaults to 20 entries from offset 0. */\n public async listVersions(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Version>> {\n return this.getListResource<Version>(ENDPOINTS.VERSION, offset, limit);\n }\n\n /** List Version Groups. Page defaults to 20 entries from offset 0. */\n public async listVersionGroups(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<VersionGroup>> {\n return this.getListResource<VersionGroup>(ENDPOINTS.VERSION_GROUP, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n Item,\n ItemAttribute,\n ItemCategory,\n ItemFlingEffect,\n ItemPocket,\n NamedAPIResourceList,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Item Client\n *\n * Client used to access the Item Endpoints:\n *\n * - [Items](https://pokeapi.co/docs/v2#item)\n * - [Item Attributes](https://pokeapi.co/docs/v2#item-attributes)\n * - [Item Categories](https://pokeapi.co/docs/v2#item-categories)\n * - [Item Fling Effects](https://pokeapi.co/docs/v2#item-fling-effects)\n * - [Item Pockets](https://pokeapi.co/docs/v2#item-pockets)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#items-section)\n */\nexport class ItemClient extends BaseClient {\n /** Get an Item by its name. */\n public async getItemByName(name: string): Promise<Item> {\n return this.getResource(ENDPOINTS.ITEM, name);\n }\n\n /** Get an Item by its ID. */\n public async getItemById(id: number): Promise<Item> {\n return this.getResource(ENDPOINTS.ITEM, id);\n }\n\n /** Get an Item Attribute by its name. */\n public async getItemAttributeByName(name: string): Promise<ItemAttribute> {\n return this.getResource(ENDPOINTS.ITEM_ATTRIBUTE, name);\n }\n\n /** Get an Item Attribute by its ID. */\n public async getItemAttributeById(id: number): Promise<ItemAttribute> {\n return this.getResource(ENDPOINTS.ITEM_ATTRIBUTE, id);\n }\n\n /** Get an Item Category by its name. */\n public async getItemCategoryByName(name: string): Promise<ItemCategory> {\n return this.getResource(ENDPOINTS.ITEM_CATEGORY, name);\n }\n\n /** Get an Item Category by its ID. */\n public async getItemCategoryById(id: number): Promise<ItemCategory> {\n return this.getResource(ENDPOINTS.ITEM_CATEGORY, id);\n }\n\n /** Get an Item Fling Effect by its name. */\n public async getItemFlingEffectByName(name: string): Promise<ItemFlingEffect> {\n return this.getResource(ENDPOINTS.ITEM_FLING_EFFECT, name);\n }\n\n /** Get an Item Fling Effect by its ID. */\n public async getItemFlingEffectById(id: number): Promise<ItemFlingEffect> {\n return this.getResource(ENDPOINTS.ITEM_FLING_EFFECT, id);\n }\n\n /** Get an Item Pocket by its name. */\n public async getItemPocketByName(name: string): Promise<ItemPocket> {\n return this.getResource(ENDPOINTS.ITEM_POCKET, name);\n }\n\n /** Get an Item Pocket by its ID. */\n public async getItemPocketById(id: number): Promise<ItemPocket> {\n return this.getResource(ENDPOINTS.ITEM_POCKET, id);\n }\n\n /** List Items. Page defaults to 20 entries from offset 0. */\n public async listItems(offset?: number, limit?: number): Promise<NamedAPIResourceList<Item>> {\n return this.getListResource<Item>(ENDPOINTS.ITEM, offset, limit);\n }\n\n /** List Item Attributes. Page defaults to 20 entries from offset 0. */\n public async listItemAttributes(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ItemAttribute>> {\n return this.getListResource<ItemAttribute>(ENDPOINTS.ITEM_ATTRIBUTE, offset, limit);\n }\n\n /** List Item Categories. Page defaults to 20 entries from offset 0. */\n public async listItemCategories(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ItemCategory>> {\n return this.getListResource<ItemCategory>(ENDPOINTS.ITEM_CATEGORY, offset, limit);\n }\n\n /** List Item Fling Effects. Page defaults to 20 entries from offset 0. */\n public async listItemFlingEffects(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ItemFlingEffect>> {\n return this.getListResource<ItemFlingEffect>(ENDPOINTS.ITEM_FLING_EFFECT, offset, limit);\n }\n\n /** List Item Pockets. Page defaults to 20 entries from offset 0. */\n public async listItemPockets(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ItemPocket>> {\n return this.getListResource<ItemPocket>(ENDPOINTS.ITEM_POCKET, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Location, LocationArea, NamedAPIResourceList, PalParkArea, Region } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Location Client\n *\n * Client used to access the Location Endpoints:\n *\n * - [Locations](https://pokeapi.co/docs/v2#locations)\n * - [Location Areas](https://pokeapi.co/docs/v2#location-areas)\n * - [Pal Park Areas](https://pokeapi.co/docs/v2#pal-park-areas)\n * - [Regions](https://pokeapi.co/docs/v2#regions)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#locations-section)\n */\nexport class LocationClient extends BaseClient {\n /** Get a Location by its name. */\n public async getLocationByName(name: string): Promise<Location> {\n return this.getResource(ENDPOINTS.LOCATION, name);\n }\n\n /** Get a Location by its ID. */\n public async getLocationById(id: number): Promise<Location> {\n return this.getResource(ENDPOINTS.LOCATION, id);\n }\n\n /** Get a Location Area by its name. */\n public async getLocationAreaByName(name: string): Promise<LocationArea> {\n return this.getResource(ENDPOINTS.LOCATION_AREA, name);\n }\n\n /** Get a Location Area by its ID. */\n public async getLocationAreaById(id: number): Promise<LocationArea> {\n return this.getResource(ENDPOINTS.LOCATION_AREA, id);\n }\n\n /** Get a Pal Park Area by its name. */\n public async getPalParkAreaByName(name: string): Promise<PalParkArea> {\n return this.getResource(ENDPOINTS.PALPARK_AREA, name);\n }\n\n /** Get a Pal Park Area by its ID. */\n public async getPalParkAreaById(id: number): Promise<PalParkArea> {\n return this.getResource(ENDPOINTS.PALPARK_AREA, id);\n }\n\n /** Get a Region by its name. */\n public async getRegionByName(name: string): Promise<Region> {\n return this.getResource(ENDPOINTS.REGION, name);\n }\n\n /** Get a Region by its ID. */\n public async getRegionById(id: number): Promise<Region> {\n return this.getResource(ENDPOINTS.REGION, id);\n }\n\n /** List Locations. Page defaults to 20 entries from offset 0. */\n public async listLocations(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Location>> {\n return this.getListResource<Location>(ENDPOINTS.LOCATION, offset, limit);\n }\n\n /** List Location Areas. Page defaults to 20 entries from offset 0. */\n public async listLocationAreas(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<LocationArea>> {\n return this.getListResource<LocationArea>(ENDPOINTS.LOCATION_AREA, offset, limit);\n }\n\n /** List Pal Park Areas. Page defaults to 20 entries from offset 0. */\n public async listPalParkAreas(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PalParkArea>> {\n return this.getListResource<PalParkArea>(ENDPOINTS.PALPARK_AREA, offset, limit);\n }\n\n /** List Regions. Page defaults to 20 entries from offset 0. */\n public async listRegions(offset?: number, limit?: number): Promise<NamedAPIResourceList<Region>> {\n return this.getListResource<Region>(ENDPOINTS.REGION, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { APIResourceList, Machine } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Machine Client\n *\n * Client used to access the Machine Endpoints:\n *\n * - [Machines](https://pokeapi.co/docs/v2#machines)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#machines-section)\n */\nexport class MachineClient extends BaseClient {\n /** Get a Machine by its ID. */\n public async getMachineById(id: number): Promise<Machine> {\n return this.getResource(ENDPOINTS.MACHINE, id);\n }\n\n /** List Machines. Page defaults to 20 entries from offset 0. */\n public async listMachines(offset?: number, limit?: number): Promise<APIResourceList<Machine>> {\n return this.getUnnamedListResource<Machine>(ENDPOINTS.MACHINE, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n Move,\n MoveAilment,\n MoveBattleStyle,\n MoveCategory,\n MoveDamageClass,\n MoveLearnMethod,\n MoveTarget,\n NamedAPIResourceList,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Move Client\n *\n * Client used to access the Move Endpoints:\n *\n * - [Moves](https://pokeapi.co/docs/v2#moves)\n * - [Move Ailments](https://pokeapi.co/docs/v2#move-ailments)\n * - [Move Battle Styles](https://pokeapi.co/docs/v2#move-battle-styles)\n * - [Move Categories](https://pokeapi.co/docs/v2#move-categories)\n * - [Move Damage Classes](https://pokeapi.co/docs/v2#move-damage-classes)\n * - [Move Learn Methods](https://pokeapi.co/docs/v2#move-learn-methods)\n * - [Move Targets](https://pokeapi.co/docs/v2#move-targets)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#moves-section)\n */\nexport class MoveClient extends BaseClient {\n /** Get a Move by its name. */\n public async getMoveByName(name: string): Promise<Move> {\n return this.getResource(ENDPOINTS.MOVE, name);\n }\n\n /** Get a Move by its ID. */\n public async getMoveById(id: number): Promise<Move> {\n return this.getResource(ENDPOINTS.MOVE, id);\n }\n\n /** Get a Move Ailment by its name. */\n public async getMoveAilmentByName(name: string): Promise<MoveAilment> {\n return this.getResource(ENDPOINTS.MOVE_AILMENT, name);\n }\n\n /** Get a Move Ailment by its ID. */\n public async getMoveAilmentById(id: number): Promise<MoveAilment> {\n return this.getResource(ENDPOINTS.MOVE_AILMENT, id);\n }\n\n /** Get a Move Battle Style by its name. */\n public async getMoveBattleStyleByName(name: string): Promise<MoveBattleStyle> {\n return this.getResource(ENDPOINTS.MOVE_BATTLE_STYLE, name);\n }\n\n /** Get a Move Battle Style by its ID. */\n public async getMoveBattleStyleById(id: number): Promise<MoveBattleStyle> {\n return this.getResource(ENDPOINTS.MOVE_BATTLE_STYLE, id);\n }\n\n /** Get a Move Category by its name. */\n public async getMoveCategoryByName(name: string): Promise<MoveCategory> {\n return this.getResource(ENDPOINTS.MOVE_CATEGORY, name);\n }\n\n /** Get a Move Category by its ID. */\n public async getMoveCategoryById(id: number): Promise<MoveCategory> {\n return this.getResource(ENDPOINTS.MOVE_CATEGORY, id);\n }\n\n /** Get a Move Damage Class by its name. */\n public async getMoveDamageClassByName(name: string): Promise<MoveDamageClass> {\n return this.getResource(ENDPOINTS.MOVE_DAMAGE_CLASS, name);\n }\n\n /** Get a Move Damage Class by its ID. */\n public async getMoveDamageClassById(id: number): Promise<MoveDamageClass> {\n return this.getResource(ENDPOINTS.MOVE_DAMAGE_CLASS, id);\n }\n\n /** Get a Move Learn Method by its name. */\n public async getMoveLearnMethodByName(name: string): Promise<MoveLearnMethod> {\n return this.getResource(ENDPOINTS.MOVE_LEARN_METHOD, name);\n }\n\n /** Get a Move Learn Method by its ID. */\n public async getMoveLearnMethodById(id: number): Promise<MoveLearnMethod> {\n return this.getResource(ENDPOINTS.MOVE_LEARN_METHOD, id);\n }\n\n /** Get a Move Target by its name. */\n public async getMoveTargetByName(name: string): Promise<MoveTarget> {\n return this.getResource(ENDPOINTS.MOVE_TARGET, name);\n }\n\n /** Get a Move Target by its ID. */\n public async getMoveTargetById(id: number): Promise<MoveTarget> {\n return this.getResource(ENDPOINTS.MOVE_TARGET, id);\n }\n\n /** List Moves. Page defaults to 20 entries from offset 0. */\n public async listMoves(offset?: number, limit?: number): Promise<NamedAPIResourceList<Move>> {\n return this.getListResource<Move>(ENDPOINTS.MOVE, offset, limit);\n }\n\n /** List Move Ailments. Page defaults to 20 entries from offset 0. */\n public async listMoveAilments(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveAilment>> {\n return this.getListResource<MoveAilment>(ENDPOINTS.MOVE_AILMENT, offset, limit);\n }\n\n /** List Move Battle Styles. Page defaults to 20 entries from offset 0. */\n public async listMoveBattleStyles(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveBattleStyle>> {\n return this.getListResource<MoveBattleStyle>(ENDPOINTS.MOVE_BATTLE_STYLE, offset, limit);\n }\n\n /** List Move Categories. Page defaults to 20 entries from offset 0. */\n public async listMoveCategories(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveCategory>> {\n return this.getListResource<MoveCategory>(ENDPOINTS.MOVE_CATEGORY, offset, limit);\n }\n\n /** List Move Damage Classes. Page defaults to 20 entries from offset 0. */\n public async listMoveDamageClasses(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveDamageClass>> {\n return this.getListResource<MoveDamageClass>(ENDPOINTS.MOVE_DAMAGE_CLASS, offset, limit);\n }\n\n /** List Move Learn Methods. Page defaults to 20 entries from offset 0. */\n public async listMoveLearnMethods(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveLearnMethod>> {\n return this.getListResource<MoveLearnMethod>(ENDPOINTS.MOVE_LEARN_METHOD, offset, limit);\n }\n\n /** List Move Targets. Page defaults to 20 entries from offset 0. */\n public async listMoveTargets(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveTarget>> {\n return this.getListResource<MoveTarget>(ENDPOINTS.MOVE_TARGET, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n Ability,\n APIResourceList,\n Characteristic,\n EggGroup,\n Gender,\n GrowthRate,\n LocationAreaEncounter,\n NamedAPIResourceList,\n Nature,\n PokeathlonStat,\n Pokemon,\n PokemonColor,\n PokemonForm,\n PokemonHabitat,\n PokemonShape,\n PokemonSpecies,\n Stat,\n Type,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Pokémon Client\n *\n * Client used to access the Pokémon Endpoints:\n *\n * - [Abilities](https://pokeapi.co/docs/v2#abilities)\n * - [Characteristics](https://pokeapi.co/docs/v2#characteristics)\n * - [Egg Groups](https://pokeapi.co/docs/v2#egg-groups)\n * - [Genders](https://pokeapi.co/docs/v2#genders)\n * - [Growth Rates](https://pokeapi.co/docs/v2#growth-rates)\n * - [Natures](https://pokeapi.co/docs/v2#natures)\n * - [Pokéathlon Stats](https://pokeapi.co/docs/v2#pokeathlon-stats)\n * - [Pokémon](https://pokeapi.co/docs/v2#pokemon)\n * - [Pokémon Location Areas](https://pokeapi.co/docs/v2#pokemon-location-areas)\n * - [Pokémon Colors](https://pokeapi.co/docs/v2#pokemon-colors)\n * - [Pokémon Forms](https://pokeapi.co/docs/v2#pokemon-forms)\n * - [Pokémon Habitats](https://pokeapi.co/docs/v2#pokemon-habitats)\n * - [Pokémon Shapes](https://pokeapi.co/docs/v2#pokemon-shapes)\n * - [Pokémon Species](https://pokeapi.co/docs/v2#pokemon-species)\n * - [Stats](https://pokeapi.co/docs/v2#stats)\n * - [Types](https://pokeapi.co/docs/v2#types)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#pokemon-section)\n */\nexport class PokemonClient extends BaseClient {\n /** Get an Ability by its name. */\n public async getAbilityByName(name: string): Promise<Ability> {\n return this.getResource(ENDPOINTS.ABILITY, name);\n }\n\n /** Get an Ability by its ID. */\n public async getAbilityById(id: number): Promise<Ability> {\n return this.getResource(ENDPOINTS.ABILITY, id);\n }\n\n /** Get a Characteristic by its ID. */\n public async getCharacteristicById(id: number): Promise<Characteristic> {\n return this.getResource(ENDPOINTS.CHARACTERISTIC, id);\n }\n\n /** Get an Egg Group by its name. */\n public async getEggGroupByName(name: string): Promise<EggGroup> {\n return this.getResource(ENDPOINTS.EGG_GROUP, name);\n }\n\n /** Get an Egg Group by its ID. */\n public async getEggGroupById(id: number): Promise<EggGroup> {\n return this.getResource(ENDPOINTS.EGG_GROUP, id);\n }\n\n /** Get a Gender by its name. */\n public async getGenderByName(name: string): Promise<Gender> {\n return this.getResource(ENDPOINTS.GENDER, name);\n }\n\n /** Get a Gender by its ID. */\n public async getGenderById(id: number): Promise<Gender> {\n return this.getResource(ENDPOINTS.GENDER, id);\n }\n\n /** Get a Growth Rate by its name. */\n public async getGrowthRateByName(name: string): Promise<GrowthRate> {\n return this.getResource(ENDPOINTS.GROWTH_RATE, name);\n }\n\n /** Get a Growth Rate by its ID. */\n public async getGrowthRateById(id: number): Promise<GrowthRate> {\n return this.getResource(ENDPOINTS.GROWTH_RATE, id);\n }\n\n /** Get a Nature by its name. */\n public async getNatureByName(name: string): Promise<Nature> {\n return this.getResource(ENDPOINTS.NATURE, name);\n }\n\n /** Get a Nature by its ID. */\n public async getNatureById(id: number): Promise<Nature> {\n return this.getResource(ENDPOINTS.NATURE, id);\n }\n\n /** Get a Pokéathlon Stat by its name. */\n public async getPokeathlonStatByName(name: string): Promise<PokeathlonStat> {\n return this.getResource(ENDPOINTS.POKEATHLON_STAT, name);\n }\n\n /** Get a Pokéathlon Stat by its ID. */\n public async getPokeathlonStatById(id: number): Promise<PokeathlonStat> {\n return this.getResource(ENDPOINTS.POKEATHLON_STAT, id);\n }\n\n /** Get a Pokémon by its name. */\n public async getPokemonByName(name: string): Promise<Pokemon> {\n return this.getResource(ENDPOINTS.POKEMON, name);\n }\n\n /** Get a Pokémon by its ID. */\n public async getPokemonById(id: number): Promise<Pokemon> {\n return this.getResource(ENDPOINTS.POKEMON, id);\n }\n\n /**\n * Get the areas a Pokémon can be encountered in, by its ID.\n * @returns Every location area the Pokémon appears in, with its encounter details.\n */\n public async getPokemonLocationAreaById(id: number): Promise<LocationAreaEncounter[]> {\n // Encounters hang off a single Pokémon rather than being an endpoint of\n // their own, so the path below `/pokemon` is addressed directly.\n return this.getResource(ENDPOINTS.POKEMON, id, \"encounters\");\n }\n\n /** Get a Pokémon Color by its name. */\n public async getPokemonColorByName(name: string): Promise<PokemonColor> {\n return this.getResource(ENDPOINTS.POKEMON_COLOR, name);\n }\n\n /** Get a Pokémon Color by its ID. */\n public async getPokemonColorById(id: number): Promise<PokemonColor> {\n return this.getResource(ENDPOINTS.POKEMON_COLOR, id);\n }\n\n /** Get a Pokémon Form by its name. */\n public async getPokemonFormByName(name: string): Promise<PokemonForm> {\n return this.getResource(ENDPOINTS.POKEMON_FORM, name);\n }\n\n /** Get a Pokémon Form by its ID. */\n public async getPokemonFormById(id: number): Promise<PokemonForm> {\n return this.getResource(ENDPOINTS.POKEMON_FORM, id);\n }\n\n /** Get a Pokémon Habitat by its name. */\n public async getPokemonHabitatByName(name: string): Promise<PokemonHabitat> {\n return this.getResource(ENDPOINTS.POKEMON_HABITAT, name);\n }\n\n /** Get a Pokémon Habitat by its ID. */\n public async getPokemonHabitatById(id: number): Promise<PokemonHabitat> {\n return this.getResource(ENDPOINTS.POKEMON_HABITAT, id);\n }\n\n /** Get a Pokémon Shape by its name. */\n public async getPokemonShapeByName(name: string): Promise<PokemonShape> {\n return this.getResource(ENDPOINTS.POKEMON_SHAPE, name);\n }\n\n /** Get a Pokémon Shape by its ID. */\n public async getPokemonShapeById(id: number): Promise<PokemonShape> {\n return this.getResource(ENDPOINTS.POKEMON_SHAPE, id);\n }\n\n /** Get a Pokémon Species by its name. */\n public async getPokemonSpeciesByName(name: string): Promise<PokemonSpecies> {\n return this.getResource(ENDPOINTS.POKEMON_SPECIES, name);\n }\n\n /** Get a Pokémon Species by its ID. */\n public async getPokemonSpeciesById(id: number): Promise<PokemonSpecies> {\n return this.getResource(ENDPOINTS.POKEMON_SPECIES, id);\n }\n\n /** Get a Stat by its name. */\n public async getStatByName(name: string): Promise<Stat> {\n return this.getResource(ENDPOINTS.STAT, name);\n }\n\n /** Get a Stat by its ID. */\n public async getStatById(id: number): Promise<Stat> {\n return this.getResource(ENDPOINTS.STAT, id);\n }\n\n /** Get a Type by its name. */\n public async getTypeByName(name: string): Promise<Type> {\n return this.getResource(ENDPOINTS.TYPE, name);\n }\n\n /** Get a Type by its ID. */\n public async getTypeById(id: number): Promise<Type> {\n return this.getResource(ENDPOINTS.TYPE, id);\n }\n\n /** List Abilities. Page defaults to 20 entries from offset 0. */\n public async listAbilities(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Ability>> {\n return this.getListResource<Ability>(ENDPOINTS.ABILITY, offset, limit);\n }\n\n /** List Characteristics. Page defaults to 20 entries from offset 0. */\n public async listCharacteristics(\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<Characteristic>> {\n return this.getUnnamedListResource<Characteristic>(ENDPOINTS.CHARACTERISTIC, offset, limit);\n }\n\n /** List Egg Groups. Page defaults to 20 entries from offset 0. */\n public async listEggGroups(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EggGroup>> {\n return this.getListResource<EggGroup>(ENDPOINTS.EGG_GROUP, offset, limit);\n }\n\n /** List Genders. Page defaults to 20 entries from offset 0. */\n public async listGenders(offset?: number, limit?: number): Promise<NamedAPIResourceList<Gender>> {\n return this.getListResource<Gender>(ENDPOINTS.GENDER, offset, limit);\n }\n\n /** List Growth Rates. Page defaults to 20 entries from offset 0. */\n public async listGrowthRates(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<GrowthRate>> {\n return this.getListResource<GrowthRate>(ENDPOINTS.GROWTH_RATE, offset, limit);\n }\n\n /** List Natures. Page defaults to 20 entries from offset 0. */\n public async listNatures(offset?: number, limit?: number): Promise<NamedAPIResourceList<Nature>> {\n return this.getListResource<Nature>(ENDPOINTS.NATURE, offset, limit);\n }\n\n /** List Pokéathlon Stats. Page defaults to 20 entries from offset 0. */\n public async listPokeathlonStats(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokeathlonStat>> {\n return this.getListResource<PokeathlonStat>(ENDPOINTS.POKEATHLON_STAT, offset, limit);\n }\n\n /** List Pokémon. Page defaults to 20 entries from offset 0. */\n public async listPokemons(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Pokemon>> {\n return this.getListResource<Pokemon>(ENDPOINTS.POKEMON, offset, limit);\n }\n\n /** List Pokémon Colors. Page defaults to 20 entries from offset 0. */\n public async listPokemonColors(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonColor>> {\n return this.getListResource<PokemonColor>(ENDPOINTS.POKEMON_COLOR, offset, limit);\n }\n\n /** List Pokémon Forms. Page defaults to 20 entries from offset 0. */\n public async listPokemonForms(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonForm>> {\n return this.getListResource<PokemonForm>(ENDPOINTS.POKEMON_FORM, offset, limit);\n }\n\n /** List Pokémon Habitats. Page defaults to 20 entries from offset 0. */\n public async listPokemonHabitats(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonHabitat>> {\n return this.getListResource<PokemonHabitat>(ENDPOINTS.POKEMON_HABITAT, offset, limit);\n }\n\n /** List Pokémon Shapes. Page defaults to 20 entries from offset 0. */\n public async listPokemonShapes(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonShape>> {\n return this.getListResource<PokemonShape>(ENDPOINTS.POKEMON_SHAPE, offset, limit);\n }\n\n /** List Pokémon Species. Page defaults to 20 entries from offset 0. */\n public async listPokemonSpecies(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonSpecies>> {\n return this.getListResource<PokemonSpecies>(ENDPOINTS.POKEMON_SPECIES, offset, limit);\n }\n\n /** List Stats. Page defaults to 20 entries from offset 0. */\n public async listStats(offset?: number, limit?: number): Promise<NamedAPIResourceList<Stat>> {\n return this.getListResource<Stat>(ENDPOINTS.STAT, offset, limit);\n }\n\n /** List Types. Page defaults to 20 entries from offset 0. */\n public async listTypes(offset?: number, limit?: number): Promise<NamedAPIResourceList<Type>> {\n return this.getListResource<Type>(ENDPOINTS.TYPE, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Language, NamedAPIResourceList } from \"@models\";\nimport { BaseClient, type ResourceLink } from \"./base\";\n\n/**\n * ### Utility Client\n *\n * Client used to access the Utility Endpoints:\n *\n * - [Languages](https://pokeapi.co/docs/v2#languages)\n * - [Resources](https://pokeapi.co/docs/v2#resource-listspagination-section)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#utility-section)\n */\nexport class UtilityClient extends BaseClient {\n /** Get a Language by its ID. */\n public async getLanguageById(id: number): Promise<Language> {\n return this.getResource(ENDPOINTS.LANGUAGE, id);\n }\n\n /** Get a Language by its name. */\n public async getLanguageByName(name: string): Promise<Language> {\n return this.getResource(ENDPOINTS.LANGUAGE, name);\n }\n\n /**\n * Get any resource by its URL, or by a link taken from another response.\n *\n * ```ts\n * const pokemon = await api.pokemon.getPokemonByName('luxray');\n * const species = await api.utility.getResourceByUrl(pokemon.species);\n * // ^? PokemonSpecies\n * ```\n *\n * Every client carries {@link BaseClient.resolve}, which does the same thing;\n * this is the name it went out under, and it stays.\n *\n * @param resource The absolute URL of the resource, or a link to it.\n * @returns The resource the URL points at.\n * @throws {TypeError} If the URL is not valid, or names no PokéAPI endpoint.\n */\n public async getResourceByUrl<T>(resource: ResourceLink<T>): Promise<T> {\n return this.resolve<T>(resource);\n }\n\n /** List Languages. Page defaults to 20 entries from offset 0. */\n public listLanguages(offset?: number, limit?: number): Promise<NamedAPIResourceList<Language>> {\n return this.getListResource<Language>(ENDPOINTS.LANGUAGE, offset, limit);\n }\n}\n","import { Transport } from \"../internal/transport\";\nimport { ClientFacade, type ClientOptions } from \"./base\";\nimport { BerryClient } from \"./berry.client\";\nimport { ContestClient } from \"./contest.client\";\nimport { CurrencyClient } from \"./currency.client\";\nimport { EncounterClient } from \"./encounter.client\";\nimport { EvolutionClient } from \"./evolution.client\";\nimport { GameClient } from \"./game.client\";\nimport { ItemClient } from \"./item.client\";\nimport { LocationClient } from \"./location.client\";\nimport { MachineClient } from \"./machine.client\";\nimport { MoveClient } from \"./move.client\";\nimport { PokemonClient } from \"./pokemon.client\";\nimport { UtilityClient } from \"./utility.client\";\n\n/**\n * ### Main Client\n *\n * The main client used to access all the PokéAPI Endpoints:\n *\n * - [Berries](https://pokeapi.co/docs/v2#berries-section)\n * - [Contests](https://pokeapi.co/docs/v2#contests-section)\n * - [Currencies](https://pokeapi.co/docs/v2#currencies-section)\n * - [Encounters](https://pokeapi.co/docs/v2#encounters-section)\n * - [Evolution](https://pokeapi.co/docs/v2#evolution-section)\n * - [Games](https://pokeapi.co/docs/v2#games-section)\n * - [Items](https://pokeapi.co/docs/v2#items-section)\n * - [Locations](https://pokeapi.co/docs/v2#locations-section)\n * - [Machines](https://pokeapi.co/docs/v2#machines-section)\n * - [Moves](https://pokeapi.co/docs/v2#moves-section)\n * - [Pokémon](https://pokeapi.co/docs/v2#pokemon-section)\n * - [Utility](https://pokeapi.co/docs/v2#utility-section)\n *\n * All the clients below share a single transport, so a resource fetched through\n * one of them is served from cache by the rest — and two of them asking for the\n * same URL at once make one round trip, not two.\n *\n * Composes its sections rather than inheriting from them: it extends\n * {@link ClientFacade}, not {@link BaseClient}, so it carries no endpoint of its\n * own.\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2)\n */\nexport class MainClient extends ClientFacade {\n public readonly berry: BerryClient;\n public readonly contest: ContestClient;\n public readonly currency: CurrencyClient;\n public readonly encounter: EncounterClient;\n public readonly evolution: EvolutionClient;\n public readonly game: GameClient;\n public readonly item: ItemClient;\n public readonly location: LocationClient;\n public readonly machine: MachineClient;\n public readonly move: MoveClient;\n public readonly pokemon: PokemonClient;\n public readonly utility: UtilityClient;\n\n constructor(options?: ClientOptions);\n /** @internal Shares the transport a client already holds. */\n constructor(source?: ClientOptions | Transport);\n constructor(source?: ClientOptions | Transport) {\n // Built here rather than read back off the facade, which keeps it private:\n // one transport handed to all twelve, so a cached response, a learned ETag\n // and a request already on the wire are each worth having in every section\n // rather than only in the one that paid for it.\n const transport = source instanceof Transport ? source : Transport.create(source);\n\n super(transport);\n\n this.berry = new BerryClient(transport);\n this.contest = new ContestClient(transport);\n this.currency = new CurrencyClient(transport);\n this.encounter = new EncounterClient(transport);\n this.evolution = new EvolutionClient(transport);\n this.game = new GameClient(transport);\n this.item = new ItemClient(transport);\n this.location = new LocationClient(transport);\n this.machine = new MachineClient(transport);\n this.move = new MoveClient(transport);\n this.pokemon = new PokemonClient(transport);\n this.utility = new UtilityClient(transport);\n }\n}\n","import type {\n ChainLink,\n EvolutionChain,\n EvolutionDetail,\n EvolutionTimeOfDay,\n EvolutionTrigger,\n EvolutionTriggerName,\n Item,\n Location,\n Move,\n NamedAPIResource,\n PokemonForm,\n PokemonSpecies,\n Region,\n Type,\n} from \"@models\";\n\n/**\n * ## Evolution Step\n * One edge of an evolution chain: a species, what it evolves into, and every way\n * that happens.\n */\nexport interface EvolutionStep {\n /** The species that evolves. */\n from: NamedAPIResource<PokemonSpecies>;\n /** What it evolves into. */\n to: NamedAPIResource<PokemonSpecies>;\n /**\n * The ways this step happens, which are alternatives rather than a sequence —\n * the API publishes one per version group, so Leafeon carries five mossy-rock\n * locations and a Leaf Stone. Never empty.\n */\n details: EvolutionDetail[];\n /** How deep in the chain this step sits: `1` for a first evolution. */\n depth: number;\n /** Whether {@link EvolutionStep.to} is a baby Pokémon. */\n isBaby: boolean;\n}\n\n/**\n * ## Flatten Options\n * How {@link flattenChain} narrows the chain it walks.\n */\nexport interface FlattenOptions {\n /**\n * Keep only the details tagged with this version group, by the name the API\n * gives it — `sword-shield`, not `Sword/Shield` — and drop the steps left with\n * none. The tag is the game that introduced the method, not every game it\n * applies in — see {@link flattenChain}.\n */\n versionGroup?: string;\n}\n\n/** The details of a link, narrowed to one version group when asked for. */\nconst detailsFor = (link: ChainLink, versionGroup: string | undefined): EvolutionDetail[] =>\n versionGroup === undefined\n ? link.evolution_details\n : link.evolution_details.filter((detail) => detail.version_group.name === versionGroup);\n\n/**\n * Flattens an evolution chain into one step per evolution, depth-first in the\n * order the API lists them.\n *\n * ```ts\n * const species = await api.pokemon.getPokemonSpeciesByName('eevee');\n * const chain = await api.resolve(species.evolution_chain);\n *\n * for (const step of flattenChain(chain)) {\n * console.log(`${step.from.name} → ${step.to.name}`);\n * }\n * ```\n *\n * The root is not a step: it is what the chain starts from, and the API gives it\n * no `evolution_details` to describe.\n *\n * `versionGroup` keeps only the details tagged with that version group, which is\n * what picks the Leaf Stone out of Leafeon's six alternatives:\n *\n * ```ts\n * flattenChain(chain, { versionGroup: 'sword-shield' });\n * ```\n *\n * That tag is the game which *introduced* the method, not every game it applies\n * in: Eevee's Water Stone is tagged `red-blue` alone, so filtering to\n * `sword-shield` drops Vaporeon even though Sword/Shield evolves it the same way\n * it always did. The question this answers is what a game changed.\n *\n * A step with nothing left after that is dropped, but the chain below it is\n * still walked — every edge is filtered on its own terms, and `depth` stays the\n * position in the chain rather than in the result.\n */\nexport const flattenChain = (chain: EvolutionChain, options?: FlattenOptions): EvolutionStep[] => {\n const collect = (link: ChainLink, depth: number): EvolutionStep[] =>\n link.evolves_to.flatMap((next) => {\n const details = detailsFor(next, options?.versionGroup);\n const below = collect(next, depth + 1);\n\n if (details.length === 0) {\n return below;\n }\n\n return [\n { from: link.species, to: next.species, details, depth, isBaby: next.is_baby },\n ...below,\n ];\n });\n\n return collect(chain.chain, 1);\n};\n\n/**\n * The steps leading from the root of a chain to `species`.\n *\n * ```ts\n * pathTo(chain, 'dustox')?.map((step) => step.to.name); // ['cascoon', 'dustox']\n * ```\n *\n * Matched against the name the API gives a species, which is not the name a game\n * displays: `localize(species.names)` is `Papilord` in French and finds nothing\n * here. Pass the link itself when you have one.\n *\n * @returns The steps, `[]` when `species` is the root the chain starts from, and\n * `undefined` when the chain does not contain it. The two empty answers are\n * different questions, so they are different values.\n */\nexport const pathTo = (\n chain: EvolutionChain,\n species: string | NamedAPIResource<PokemonSpecies>,\n): EvolutionStep[] | undefined => {\n const wanted = typeof species === \"string\" ? species : species.name;\n\n const search = (link: ChainLink, trail: EvolutionStep[]): EvolutionStep[] | undefined => {\n if (link.species.name === wanted) {\n return trail;\n }\n\n for (const next of link.evolves_to) {\n const step: EvolutionStep = {\n from: link.species,\n to: next.species,\n details: next.evolution_details,\n depth: trail.length + 1,\n isBaby: next.is_baby,\n };\n const found = search(next, [...trail, step]);\n\n if (found !== undefined) {\n return found;\n }\n }\n\n return undefined;\n };\n\n return search(chain.chain, []);\n};\n\n/**\n * ## Evolution Requirement\n * One condition an evolution is subject to, as a discriminated union — what an\n * {@link EvolutionDetail}'s thirty-odd nullable fields say, without the nulls.\n *\n * `is_default` and `version_group` are not here: they describe the record, not\n * what the Pokémon has to do.\n */\nexport type EvolutionRequirement =\n | { kind: \"trigger\"; trigger: NamedAPIResource<EvolutionTrigger> }\n | { kind: \"item\"; item: NamedAPIResource<Item> }\n | { kind: \"held-item\"; item: NamedAPIResource<Item> }\n | { kind: \"min-level\"; level: number }\n | { kind: \"min-happiness\"; happiness: number }\n | { kind: \"min-beauty\"; beauty: number }\n | { kind: \"min-affection\"; affection: number }\n | { kind: \"known-move\"; move: NamedAPIResource<Move> }\n | { kind: \"known-move-type\"; type: NamedAPIResource<Type> }\n | { kind: \"used-move\"; move: NamedAPIResource<Move> }\n | { kind: \"min-move-count\"; count: number }\n | { kind: \"min-steps\"; steps: number }\n | { kind: \"min-damage-taken\"; damage: number }\n | { kind: \"location\"; location: NamedAPIResource<Location> }\n | { kind: \"region\"; region: NamedAPIResource<Region> }\n | { kind: \"time-of-day\"; time: EvolutionTimeOfDay }\n | { kind: \"gender\"; gender: number }\n | { kind: \"relative-physical-stats\"; comparison: 1 | 0 | -1 }\n | { kind: \"party-species\"; species: NamedAPIResource<PokemonSpecies> }\n | { kind: \"party-type\"; type: NamedAPIResource<Type> }\n | { kind: \"trade-species\"; species: NamedAPIResource<PokemonSpecies> }\n | { kind: \"base-form\"; form: NamedAPIResource<PokemonForm> }\n | { kind: \"evolved-form\"; form: NamedAPIResource<PokemonForm> }\n | { kind: \"needs-overworld-rain\" }\n | { kind: \"turn-upside-down\" }\n | { kind: \"near-special-rock\" }\n | { kind: \"needs-multiplayer\" };\n\n/**\n * One reader per field an {@link EvolutionDetail} can set, in the order the\n * requirements come out, each `null` when its field is unset.\n */\nconst READERS: ((detail: EvolutionDetail) => EvolutionRequirement | null)[] = [\n ({ item }) => (item === null ? null : { kind: \"item\", item }),\n ({ held_item: item }) => (item === null ? null : { kind: \"held-item\", item }),\n ({ min_level: level }) => (level === null ? null : { kind: \"min-level\", level }),\n ({ min_happiness: happiness }) =>\n happiness === null ? null : { kind: \"min-happiness\", happiness },\n ({ min_beauty: beauty }) => (beauty === null ? null : { kind: \"min-beauty\", beauty }),\n ({ min_affection: affection }) =>\n affection === null ? null : { kind: \"min-affection\", affection },\n ({ known_move: move }) => (move === null ? null : { kind: \"known-move\", move }),\n ({ known_move_type: type }) => (type === null ? null : { kind: \"known-move-type\", type }),\n ({ used_move: move }) => (move === null ? null : { kind: \"used-move\", move }),\n ({ min_move_count: count }) => (count === null ? null : { kind: \"min-move-count\", count }),\n ({ min_steps: steps }) => (steps === null ? null : { kind: \"min-steps\", steps }),\n ({ min_damage_taken: damage }) => (damage === null ? null : { kind: \"min-damage-taken\", damage }),\n ({ location }) => (location === null ? null : { kind: \"location\", location }),\n ({ region }) => (region === null ? null : { kind: \"region\", region }),\n ({ time_of_day: time }) => (time === \"\" ? null : { kind: \"time-of-day\", time }),\n ({ gender }) => (gender === null ? null : { kind: \"gender\", gender }),\n ({ relative_physical_stats: comparison }) =>\n comparison === null ? null : { kind: \"relative-physical-stats\", comparison },\n ({ party_species: species }) => (species === null ? null : { kind: \"party-species\", species }),\n ({ party_type: type }) => (type === null ? null : { kind: \"party-type\", type }),\n ({ trade_species: species }) => (species === null ? null : { kind: \"trade-species\", species }),\n ({ base_form: form }) => (form === null ? null : { kind: \"base-form\", form }),\n ({ evolved_form: form }) => (form === null ? null : { kind: \"evolved-form\", form }),\n ({ needs_overworld_rain: rain }) => (rain ? { kind: \"needs-overworld-rain\" } : null),\n ({ turn_upside_down: upsideDown }) => (upsideDown ? { kind: \"turn-upside-down\" } : null),\n ({ near_special_rock: rock }) => (rock ? { kind: \"near-special-rock\" } : null),\n ({ needs_multiplayer: multiplayer }) => (multiplayer ? { kind: \"needs-multiplayer\" } : null),\n];\n\n/**\n * The conditions one {@link EvolutionDetail} sets out, with everything it left\n * unset dropped.\n *\n * ```ts\n * requirementsOf(step.details[0]); // eevee → umbreon\n * // [\n * // { kind: 'trigger', trigger: { name: 'level-up', … } },\n * // { kind: 'min-happiness', happiness: 160 },\n * // { kind: 'time-of-day', time: 'night' },\n * // { kind: 'base-form', form: { name: 'eevee', … } },\n * // ]\n * ```\n *\n * The trigger leads, so rendering the result is a walk over one array.\n *\n * Every field is tested against the value the API uses for \"unset\" rather than\n * for truthiness: `relative_physical_stats` is `0` when Attack has to equal\n * Defense, and `time_of_day` is `''`.\n */\nexport const requirementsOf = (detail: EvolutionDetail): EvolutionRequirement[] => [\n { kind: \"trigger\", trigger: detail.trigger },\n ...READERS.flatMap((read) => read(detail) ?? []),\n];\n\n/**\n * Every trigger as a verb phrase. Exhaustive over {@link EvolutionTriggerName},\n * so a trigger added to that union has to be given words here too.\n */\nconst TRIGGERS: Record<EvolutionTriggerName, string> = {\n \"level-up\": \"level up\",\n trade: \"trade\",\n \"use-item\": \"use an item\",\n shed: \"shed\",\n spin: \"spin\",\n \"tower-of-darkness\": \"train in the Tower of Darkness\",\n \"tower-of-waters\": \"train in the Tower of Waters\",\n \"three-critical-hits\": \"land three critical hits in one battle\",\n \"take-damage\": \"take damage\",\n other: \"an in-game event\",\n \"agile-style-move\": \"use agile style moves\",\n \"strong-style-move\": \"use strong style moves\",\n \"recoil-damage\": \"take recoil damage\",\n \"use-move\": \"use a move\",\n \"three-defeated-bisharp\": \"defeat three pack-leading Bisharp\",\n \"gimmighoul-coins\": \"collect Gimmighoul Coins\",\n};\n\n/** A resource name as prose: the API writes them kebab-cased and lower case. */\nconst spaced = (resource: NamedAPIResource<unknown>): string => resource.name.replaceAll(\"-\", \" \");\n\n/**\n * Every time of day as a phrase. Exhaustive over {@link EvolutionTimeOfDay}, so\n * a value added to that union has to be given words here too — `dusk` and\n * `full-moon` do not fit the \"during the …\" the other two take.\n */\nconst TIMES: Record<EvolutionTimeOfDay, string> = {\n day: \"during the day\",\n night: \"during the night\",\n dusk: \"at dusk\",\n \"full-moon\": \"under a full moon\",\n};\n\nconst GENDERS: Record<number, string> = { 1: \"female\", 2: \"male\", 3: \"genderless\" };\n\n/** Unknown ids name themselves, so a gender added upstream still renders. */\nconst genderName = (gender: number): string => GENDERS[gender] ?? `gender ${gender}`;\n\nconst COMPARISONS: Record<string, string> = { \"1\": \">\", \"0\": \"=\", \"-1\": \"<\" };\n\n/**\n * ## Requirement Phrases\n * One renderer per {@link EvolutionRequirement} kind. Exhaustive, so a kind added\n * to that union has to be given words here too.\n */\nexport type RequirementPhrases = {\n [K in EvolutionRequirement[\"kind\"]]: (\n requirement: Extract<EvolutionRequirement, { kind: K }>,\n ) => string;\n};\n\n/**\n * ## Resource Namer\n * How a resource a requirement names is written out.\n *\n * @param resource The item, move, species, location, region, form or type the\n * requirement carries.\n * @returns What to print for it.\n */\nexport type ResourceNamer = (resource: NamedAPIResource<unknown>) => string;\n\n/**\n * Builds the English table around a way of naming resources.\n *\n * Everything except the name is fixed; `namer` is the one thing a caller who\n * keeps the English sentence still has to replace, because `spaced` prints what\n * the API calls a resource and no localized name is derivable from it.\n *\n * ```ts\n * const names = new Map([['water-stone', 'Pedra da Água']]);\n *\n * requirementPhrases((resource) => names.get(resource.name) ?? resource.name);\n * ```\n *\n * @param namer How to write a resource out. Defaults to the API's own name, with\n * the hyphens turned to spaces.\n */\nexport const requirementPhrases = (namer: ResourceNamer = spaced): RequirementPhrases => ({\n trigger: ({ trigger }) => TRIGGERS[trigger.name as EvolutionTriggerName] ?? namer(trigger),\n item: ({ item }) => `use ${namer(item)}`,\n \"held-item\": ({ item }) => `holding ${namer(item)}`,\n \"min-level\": ({ level }) => `at level ${level}`,\n \"min-happiness\": ({ happiness }) => `with at least ${happiness} happiness`,\n \"min-beauty\": ({ beauty }) => `with at least ${beauty} beauty`,\n \"min-affection\": ({ affection }) => `with at least ${affection} affection`,\n \"known-move\": ({ move }) => `knowing ${namer(move)}`,\n \"known-move-type\": ({ type }) => `knowing a ${namer(type)}-type move`,\n \"used-move\": ({ move }) => `after using ${namer(move)}`,\n \"min-move-count\": ({ count }) => `${count} times`,\n \"min-steps\": ({ steps }) => `after ${steps} steps`,\n \"min-damage-taken\": ({ damage }) => `after taking ${damage} damage`,\n location: ({ location }) => `at ${namer(location)}`,\n region: ({ region }) => `in ${namer(region)}`,\n \"time-of-day\": ({ time }) => TIMES[time],\n gender: ({ gender }) => `as a ${genderName(gender)}`,\n \"relative-physical-stats\": ({ comparison }) =>\n `with Attack ${COMPARISONS[String(comparison)]} Defense`,\n \"party-species\": ({ species }) => `with ${namer(species)} in the party`,\n \"party-type\": ({ type }) => `with a ${namer(type)}-type in the party`,\n \"trade-species\": ({ species }) => `traded for ${namer(species)}`,\n \"base-form\": ({ form }) => `in its ${namer(form)} form`,\n \"evolved-form\": ({ form }) => `into its ${namer(form)} form`,\n \"needs-overworld-rain\": () => \"while it is raining\",\n \"turn-upside-down\": () => \"with the console upside down\",\n \"near-special-rock\": () => \"near a special rock\",\n \"needs-multiplayer\": () => \"in multiplayer\",\n});\n\n/**\n * ## Requirement Phrases\n * The English {@link formatRequirements} renders with, naming resources the way\n * the API does. Exported so a caller can replace the wording of one kind — or\n * all of them, in another language — without rebuilding the rest of the renderer\n * around it, and so an override can fall back to the default for what it does\n * not handle.\n *\n * ```ts\n * formatRequirements(requirements, {\n * phrases: { 'min-happiness': ({ happiness }) => `com ${happiness} de felicidade` },\n * });\n *\n * formatRequirements(requirements, {\n * phrases: {\n * trigger: (requirement) => MINE[requirement.trigger.name] ?? REQUIREMENT_PHRASES.trigger(requirement),\n * },\n * });\n * ```\n */\nexport const REQUIREMENT_PHRASES: RequirementPhrases = requirementPhrases();\n\n/**\n * The table built for a namer, kept so that rendering a list does not rebuild\n * twenty-seven closures per row. Weak, so a namer closed over a component's\n * props is not held alive by having been used once.\n */\nconst tables = new WeakMap<ResourceNamer, RequirementPhrases>();\n\nconst tableFor = (namer: ResourceNamer | undefined): RequirementPhrases => {\n if (namer === undefined) {\n return REQUIREMENT_PHRASES;\n }\n\n const built = tables.get(namer) ?? requirementPhrases(namer);\n tables.set(namer, built);\n\n return built;\n};\n\n/**\n * The table is keyed by `kind` and the union is discriminated by it, so the two\n * are known to line up — but only one entry at a time, which is not something an\n * index of the whole table can be written to say.\n */\nconst phrase = (requirement: EvolutionRequirement, phrases: RequirementPhrases): string =>\n (phrases[requirement.kind] as (value: EvolutionRequirement) => string)(requirement);\n\n/**\n * ## Format Options\n * How {@link formatRequirements} words what it renders.\n */\nexport interface FormatOptions {\n /**\n * How to write out the resources the requirements name. Defaults to the API's\n * own name with the hyphens turned to spaces — `water stone`.\n *\n * This is the half of a translation that `phrases` cannot do: a display name\n * is `localize(item.names)`, which is a request, so it has to come from the\n * caller. Applied to the default table, and to nothing a `phrases` entry\n * overrides — that entry is handed the resource and names it however it likes.\n *\n * Hold the function rather than writing it inline: the table built around a\n * namer is kept and reused, and a new closure per call is a new table per call.\n */\n name?: ResourceNamer;\n /**\n * Wording for the kinds named, {@link REQUIREMENT_PHRASES} for the rest —\n * everything around it, including the `use-item` de-duplication, stays.\n */\n phrases?: Partial<RequirementPhrases>;\n}\n\n/**\n * Renders requirements as an English phrase.\n *\n * ```ts\n * formatRequirements(requirementsOf(detail)); // eevee → umbreon\n * // 'level up, with at least 160 happiness, during the night, in its eevee form'\n * ```\n *\n * The only English in the library, and a separate export for that reason: an\n * application rendering its own copy — in its own language, or as anything other\n * than a sentence — drops this and the phrase table with it. Use\n * {@link requirementsOf} for that, or `phrases` to keep the sentence and change\n * the words:\n *\n * ```ts\n * formatRequirements(requirements, { phrases: { trade: () => 'by trade' } });\n * ```\n *\n * Resources are named the way the API names them, not the way a game displays\n * them. `localize(item.names)` is the display name, it costs a request, and\n * `name` is where it goes:\n *\n * ```ts\n * const items = await api.resolveAll(links);\n * const display = new Map(items.map((item) => [item.name, localize(item.names)?.name]));\n *\n * formatRequirements(requirements, { name: (resource) => display.get(resource.name) ?? resource.name });\n * // 'use Water Stone'\n * ```\n *\n * The two options are the two halves of a translation and are independent:\n * `phrases` is the words the library supplies, `name` the words the API does.\n *\n * A `use-item` trigger and the item it uses are one phrase, since \"use an item,\n * use water stone\" says it twice. That holds under `phrases` too: the trigger is\n * dropped before anything is rendered, so an overridden `item` is still what says\n * the item is used.\n */\nexport const formatRequirements = (\n requirements: readonly EvolutionRequirement[],\n options?: FormatOptions,\n): string => {\n const phrases = { ...tableFor(options?.name), ...options?.phrases };\n\n const usesItem =\n requirements.some((requirement) => requirement.kind === \"item\") &&\n requirements.some(\n (requirement) => requirement.kind === \"trigger\" && requirement.trigger.name === \"use-item\",\n );\n\n return requirements\n .filter((requirement) => !(usesItem && requirement.kind === \"trigger\"))\n .map((requirement) => phrase(requirement, phrases))\n .join(\", \");\n};\n","import type { Language, NamedAPIResource } from \"@models\";\n\n/**\n * ## Localized\n * An entry the PokéAPI publishes once per language — a `Name`, `FlavorText`,\n * `Description`, `Effect`, `VerboseEffect`, and everything shaped like them.\n */\nexport interface Localized {\n language: NamedAPIResource<Language>;\n}\n\n/**\n * ## Localize Options\n * Which language to pick, and which to settle for.\n */\nexport interface LocalizeOptions {\n /** The language wanted, by the name the PokéAPI gives it. Defaults to `en`. */\n language?: string;\n /**\n * The language to try when the first one is absent. Left out, nothing is tried\n * and the answer is `undefined` — a fallback is a decision about the product,\n * not a default.\n */\n fallback?: string;\n}\n\nconst optionsOf = (\n language: string | LocalizeOptions | undefined,\n): LocalizeOptions & { language: string } => {\n const options = typeof language === \"string\" ? { language } : (language ?? {});\n\n return { ...options, language: options.language ?? \"en\" };\n};\n\n/** Every entry written in one language, matched without regard to case. */\nconst inLanguage = <T extends Localized>(entries: readonly T[], language: string): T[] => {\n const wanted = language.toLowerCase();\n\n return entries.filter((entry) => entry.language.name.toLowerCase() === wanted);\n};\n\n/**\n * Picks the entry written in `language`, by the name the PokéAPI gives that\n * language: `en`, `ja`, `ja-hrkt`, `zh-hans`, `es-419`, and so on.\n *\n * ```ts\n * const species = await api.pokemon.getPokemonSpeciesByName('eevee');\n *\n * localize(species.names)?.name; // 'Eevee'\n * localize(species.names, 'ja')?.name; // 'イーブイ'\n * localize(species.names, { language: 'gd', fallback: 'en' })?.name; // 'Eevee'\n * ```\n *\n * Matched without regard to case: the PokéAPI writes these tags in lower case,\n * while BCP 47 capitalizes the script subtag — `ja-Hrkt` is the form anyone used\n * to language tags will reach for, and it should not silently match nothing.\n *\n * A section may list several entries for one language — flavor text, one per\n * version — and the first is the one returned. {@link localizeAll} is the way to\n * see the rest and pick by version.\n *\n * @returns The entry, the one in `fallback` when that language is absent, or\n * `undefined` when neither is there.\n */\nexport const localize = <T extends Localized>(\n entries: readonly T[],\n language?: string | LocalizeOptions,\n): T | undefined => localizeAll(entries, language)[0];\n\n/**\n * Every entry written in `language`, in the order the API lists them.\n *\n * ```ts\n * const species = await api.pokemon.getPokemonSpeciesByName('eevee');\n *\n * const entries = localizeAll(species.flavor_text_entries, 'en');\n * entries.find((entry) => entry.version.name === 'sword')?.flavor_text;\n * ```\n *\n * Which is what a section publishing one entry per version needs: `localize`\n * answers with the first, and the first is an arbitrary game's Pokédex entry\n * rather than the one asked for. The version is on the entry — `version` on\n * flavor text, `version_group` on the sections that change per group — so the\n * filter belongs to the caller, who knows which of the two is there.\n *\n * @returns The entries, those in `fallback` when the language is absent, or `[]`\n * when neither is there.\n */\nexport const localizeAll = <T extends Localized>(\n entries: readonly T[],\n language?: string | LocalizeOptions,\n): T[] => {\n const options = optionsOf(language);\n const matched = inLanguage(entries, options.language);\n\n if (matched.length > 0 || options.fallback === undefined) {\n return matched;\n }\n\n return inLanguage(entries, options.fallback);\n};\n","// Relative rather than through `@clients`, which does not export `base.ts`.\nimport type { ResourceLink } from \"../clients/base\";\n\n/**\n * The trailing id of a PokéAPI resource URL, with or without the final slash.\n *\n * Signed: `move-ailment/-1` is the \"unknown\" ailment, and it is a resource the\n * API lists and serves like any other.\n */\nconst TRAILING_ID = /\\/(-?\\d+)\\/?$/;\n\n/**\n * The id inside a resource URL, without a request.\n *\n * ```ts\n * const page = await api.pokemon.listPokemons(0, 20);\n *\n * page.results.map((link) => getPokemonSpriteUrl(resourceId(link)));\n * ```\n *\n * A list page gives names and URLs and no ids, while the sprite repository is\n * keyed by id alone — this is what joins the two, and it is what lets a grid of\n * every Pokémon render off one list request instead of one request per card.\n *\n * The id is read off the URL rather than fetched, so it is only as good as the\n * link: a URL the API did not write is not promised to end in one.\n *\n * @param resource The link, as a URL or as the resource object carrying one.\n * @returns The id.\n * @throws {TypeError} If the URL does not end in an id.\n */\nexport const resourceId = (resource: ResourceLink<unknown>): number => {\n const url = typeof resource === \"string\" ? resource : resource.url;\n const match = TRAILING_ID.exec(url);\n\n if (match === null) {\n throw new TypeError(`No resource id in URL: ${url}`);\n }\n\n return Number(match[1]);\n};\n","import { BASE_URL } from \"@constants\";\n\n/**\n * ## Sprite Variant\n * The sprite sets the PokéAPI publishes for a Pokémon.\n */\nexport type SpriteVariant = \"default\" | \"official-artwork\" | \"home\" | \"dream-world\" | \"showdown\";\n\n/**\n * ## Pokemon Sprite Options\n * Which sprite to build a URL for.\n *\n * The sets do not carry the same images, so the options are constrained per\n * variant: only `default` and `showdown` have back-facing sprites, and only\n * `official-artwork` has no gendered ones.\n */\nexport type PokemonSpriteOptions =\n | { variant?: \"default\"; shiny?: boolean; back?: boolean; female?: boolean }\n | { variant: \"showdown\"; shiny?: boolean; back?: boolean; female?: boolean }\n | { variant: \"home\"; shiny?: boolean; female?: boolean; back?: never }\n | { variant: \"official-artwork\"; shiny?: boolean; back?: never; female?: never }\n | { variant: \"dream-world\"; female?: boolean; shiny?: never; back?: never };\n\ninterface VariantSpec {\n /** Path under `sprites/pokemon`. Empty for the default set, which sits at the root. */\n directory: string;\n extension: string;\n}\n\nconst VARIANTS: Record<SpriteVariant, VariantSpec> = {\n default: { directory: \"\", extension: \"png\" },\n \"official-artwork\": { directory: \"other/official-artwork\", extension: \"png\" },\n home: { directory: \"other/home\", extension: \"png\" },\n \"dream-world\": { directory: \"other/dream-world\", extension: \"svg\" },\n showdown: { directory: \"other/showdown\", extension: \"gif\" },\n};\n\n/**\n * Builds the URL of a Pokémon sprite, without a request.\n *\n * ```ts\n * getPokemonSpriteUrl(25); // front, default set\n * getPokemonSpriteUrl(25, { variant: \"official-artwork\" });\n * getPokemonSpriteUrl(25, { variant: \"showdown\", back: true, shiny: true });\n * ```\n *\n * The sprite repository does not hold every combination for every Pokémon — a\n * back-facing sprite of a recent generation, or a gendered form of a species with\n * one appearance, simply does not exist. This builds a well-formed URL; it does\n * not promise the file is there.\n *\n * @param id The Pokémon ID. Names are not addressable — the sprites are keyed by ID.\n * @param options Which sprite set and which facing to build for.\n * @returns The URL of the sprite.\n */\nexport const getPokemonSpriteUrl = (id: number, options: PokemonSpriteOptions = {}): string => {\n const { variant = \"default\", shiny = false, back = false, female = false } = options;\n const { directory, extension } = VARIANTS[variant];\n\n // The repository nests the modifiers in this order, so `back/shiny/female` is\n // the only path that resolves.\n const segments = [directory, back && \"back\", shiny && \"shiny\", female && \"female\"];\n\n return [BASE_URL.SPRITES, \"pokemon\", ...segments.filter(Boolean), `${id}.${extension}`].join(\"/\");\n};\n","import { GENERATIONS, type GenerationName, TYPES, type TypeName } from \"@constants\";\nimport type { NamedAPIResource, Type, TypeRelations } from \"@models\";\n\n/**\n * The names {@link TypeName} declares, at runtime. Read off {@link TYPES} by id\n * rather than written out a second time: `unknown` and `shadow` are the ids above\n * 10000, the way every other section marks what is not part of the main games.\n *\n * `constants.live.spec.ts` is what holds the two to the same set — the ids are\n * upstream's, and a type arriving above 10000 that does belong in a matchup would\n * pass here unnoticed.\n */\nconst TYPE_NAMES: ReadonlySet<string> = new Set(\n Object.entries(TYPES)\n .filter(([, id]) => id < 10_000)\n .map(([key]) => key.toLowerCase()),\n);\n\nconst isTypeName = (name: string): name is TypeName => TYPE_NAMES.has(name);\n\n/** A generation {@link GENERATIONS} does not know, which is one this build predates. */\nconst UNKNOWN = -1;\n\n/**\n * The id {@link GENERATIONS} gives a generation, or {@link UNKNOWN} for a name\n * that is not one. Generations are compared by this rather than by name, which\n * does not sort.\n */\nconst rank = (name: string): number => {\n const key = name.toUpperCase().replaceAll(\"-\", \"_\") as keyof typeof GENERATIONS;\n\n return GENERATIONS[key] ?? UNKNOWN;\n};\n\n/** The offensive arrays of a {@link TypeRelations}, and what each one means. */\nconst MULTIPLIERS: readonly (readonly [keyof TypeRelations, number])[] = [\n [\"no_damage_to\", 0],\n [\"half_damage_to\", 0.5],\n [\"double_damage_to\", 2],\n];\n\n/** The defensive arrays, which say the same thing from the other side. */\nconst INCOMING: readonly (readonly [keyof TypeRelations, number])[] = [\n [\"no_damage_from\", 0],\n [\"half_damage_from\", 0.5],\n [\"double_damage_from\", 2],\n];\n\n/** Looks one type up in a set of arrays. Unlisted is neutral. */\nconst lookup = (\n relations: TypeRelations,\n arrays: readonly (readonly [keyof TypeRelations, number])[],\n name: string,\n): number => {\n for (const [key, multiplier] of arrays) {\n if (relations[key].some((type) => type.name === name)) {\n return multiplier;\n }\n }\n\n return 1;\n};\n\n/** What one attacking type does to one defending type. */\nconst against = (relations: TypeRelations, defending: string): number =>\n lookup(relations, MULTIPLIERS, defending);\n\n/** The multiplier a set of relations produces against every defending type. */\nconst multiply = (relations: TypeRelations, defending: readonly NamedAPIResource<Type>[]): number =>\n defending.reduce((total, type) => total * against(relations, type.name), 1);\n\n/**\n * ## Generation Scope\n * Which generation's type chart to read. Leave it out for the current one.\n */\nexport interface GenerationScope {\n generation?: GenerationName;\n}\n\n/**\n * The damage relations `type` had in `generation`, or the current ones when no\n * generation is named.\n *\n * ```ts\n * const ghost = await api.pokemon.getTypeByName('ghost');\n *\n * relationsFor(ghost).half_damage_to; // [dark]\n * relationsFor(ghost, 'generation-iii')?.half_damage_to; // [dark, steel]\n * ```\n *\n * Each entry in `past_damage_relations` records the *last* generation it applied\n * to, so the chart in force is the first entry still at or after the generation\n * asked for — Ghost's `generation-v` entry is what Ghost looked like from II\n * through V, and the current relations take over at VI.\n *\n * @returns The relations, or `undefined` when `type` did not exist yet in\n * `generation`. Nothing is guessed: Steel in generation I has no chart, and a\n * neutral one would be a confidently wrong answer rather than a missing one.\n */\nexport const relationsFor = (\n type: Type,\n generation?: GenerationName,\n): TypeRelations | undefined => {\n if (generation === undefined) {\n return type.damage_relations;\n }\n\n const wanted = rank(generation);\n\n // A generation this build has never heard of is a later one than it knows, so\n // the current chart is the best answer available. Ranking it -1 instead would\n // put it before every type's debut and report that nothing existed yet, which\n // is the same wrong answer the check below exists to avoid.\n if (wanted === UNKNOWN) {\n return type.damage_relations;\n }\n\n // Checked before the entries are: Steel's only past entry is `generation-v`,\n // which would otherwise answer for generation I, where Steel did not exist.\n if (wanted < rank(type.generation.name)) {\n return undefined;\n }\n\n // Sorted rather than trusted: the rule below is \"the first entry still at or\n // after\", and first means nothing in an order upstream never promised.\n const past = [...type.past_damage_relations]\n .sort((left, right) => rank(left.generation.name) - rank(right.generation.name))\n .find((entry) => rank(entry.generation.name) >= wanted);\n\n return past?.damage_relations ?? type.damage_relations;\n};\n\n/**\n * The damage multiplier `attacking` deals to a defender that has `defending`\n * types — `0`, `0.25`, `0.5`, `1`, `2` or `4`.\n *\n * ```ts\n * const fire = await api.pokemon.getTypeByName('fire');\n * const ferrothorn = await api.pokemon.getPokemonByName('ferrothorn');\n *\n * effectiveness(fire, ferrothorn.types.map((slot) => slot.type)); // 4\n * ```\n *\n * Read from the attacking type's own offensive relations, so this needs the one\n * type fetched rather than one per defending type.\n *\n * With a `generation`, the chart of that generation is used and the result is\n * `undefined` when `attacking` postdates it. Only the attacker is checked that\n * way: the defenders arrive as links, which carry no generation to check\n * against. `Pokemon.past_types` is where a historically correct defender comes\n * from.\n */\nexport function effectiveness(\n attacking: Type,\n defending: readonly NamedAPIResource<Type>[],\n): number;\nexport function effectiveness(\n attacking: Type,\n defending: readonly NamedAPIResource<Type>[],\n options: { generation: GenerationName },\n): number | undefined;\nexport function effectiveness(\n attacking: Type,\n defending: readonly NamedAPIResource<Type>[],\n options?: GenerationScope,\n): number | undefined {\n const relations = relationsFor(attacking, options?.generation);\n\n return relations === undefined ? undefined : multiply(relations, defending);\n}\n\n/**\n * What every one of `types` does to a defender that has `defending` types, keyed\n * by attacking type name — the \"what is this Pokémon weak to\" table.\n *\n * ```ts\n * const types: Type[] = [];\n * for await (const type of api.pokemon.paginate('listTypes', { resolve: true })) {\n * types.push(type);\n * }\n *\n * const profile = defensiveProfile(types, gengar.types.map((slot) => slot.type));\n * profile.psychic; // 2\n * profile.normal; // 0\n * ```\n *\n * The whole `type` section is one cached walk, and every lookup after that is\n * local. A type that did not exist in the generation asked for is left out of the\n * table rather than reported as neutral.\n *\n * `Partial` because of that, and because `types` is whatever the caller resolved:\n * an entry is there when the attacking type is, so every lookup is `number |\n * undefined`. `unknown` and `shadow` are not {@link TypeName}s and are skipped —\n * they hold no damage relations, so they have no place in a matchup table.\n *\n * Reach for {@link defensiveProfileFrom} unless you are asking about a past\n * generation: it answers the same question from the defender's own types, which\n * is one or two resources rather than the whole section. This is the form that\n * takes a `generation`, because only the attacking type carries the history.\n *\n * Keyed by the name the API gives a type, which is not the name a game displays:\n * `localize(type.names)` is what a table headed in French needs, and it is a\n * property of the resource rather than of this table.\n */\nexport const defensiveProfile = (\n types: readonly Type[],\n defending: readonly NamedAPIResource<Type>[],\n options?: GenerationScope,\n): Partial<Record<TypeName, number>> => {\n const profile: Partial<Record<TypeName, number>> = {};\n\n for (const attacking of types) {\n if (!isTypeName(attacking.name)) {\n continue;\n }\n\n const relations = relationsFor(attacking, options?.generation);\n\n if (relations !== undefined) {\n profile[attacking.name] = multiply(relations, defending);\n }\n }\n\n return profile;\n};\n\n/**\n * The same table, read off the defending types themselves — what every type does\n * to a Pokémon that has `defending` types.\n *\n * ```ts\n * const gengar = await api.pokemon.getPokemonByName('gengar');\n * const types = await api.resolveAll(gengar.types.map((slot) => slot.type));\n *\n * const profile = defensiveProfileFrom(types);\n * profile.psychic; // 2\n * profile.normal; // 0\n * ```\n *\n * Two requests for a dual-typed Pokémon, against the whole `type` section that\n * {@link defensiveProfile} needs — the answer is the same because the chart is\n * symmetric, which `tests/live/relations.live.spec.ts` is what keeps honest.\n *\n * Every {@link TypeName} is present: the defending types name every attacker\n * they interact with, and the rest are neutral rather than unknown. There is no\n * `generation` option for exactly the reason the entries are total — a defending\n * type's arrays are the current chart, and they have no way to say that an\n * attacking type did not exist yet. That question needs {@link defensiveProfile}.\n *\n * Keyed by the API's name for a type, as {@link defensiveProfile} is;\n * `localize(type.names)` is the displayed one.\n */\nexport const defensiveProfileFrom = (defending: readonly Type[]): Record<TypeName, number> => {\n // Total rather than `Partial`, and asserted because the loop is what makes it\n // so: `TYPE_NAMES` is {@link TypeName}'s own runtime image, and\n // `constants.live.spec.ts` is what holds the two to the same set.\n const profile = {} as Record<TypeName, number>;\n\n for (const name of TYPE_NAMES) {\n profile[name as TypeName] = defending.reduce(\n (total, type) => total * lookup(type.damage_relations, INCOMING, name),\n 1,\n );\n }\n\n return profile;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["walkPages","#transport","GENDERS"],"sources":["../src/constants/berries.ts","../src/constants/contests.ts","../src/constants/currencies.ts","../src/constants/encounters.ts","../src/constants/endpoints.ts","../src/constants/evolutions.ts","../src/constants/games.ts","../src/constants/items.ts","../src/constants/locations.ts","../src/constants/moves.ts","../src/constants/pokemon.ts","../src/constants/urls.ts","../src/constants/utilities.ts","../src/constants/index.ts","../src/config/cache.ts","../src/config/errors.ts","../src/config/logger.ts","../src/internal/inflight.ts","../src/internal/pool.ts","../src/internal/paginate.ts","../src/internal/retry.ts","../src/internal/url.ts","../src/internal/transport.ts","../src/clients/base.ts","../src/clients/berry.client.ts","../src/clients/contest.client.ts","../src/clients/currency.client.ts","../src/clients/encounter.client.ts","../src/clients/evolution.client.ts","../src/clients/game.client.ts","../src/clients/item.client.ts","../src/clients/location.client.ts","../src/clients/machine.client.ts","../src/clients/move.client.ts","../src/clients/pokemon.client.ts","../src/clients/utility.client.ts","../src/clients/main.client.ts","../src/utils/evolution.ts","../src/utils/localize.ts","../src/utils/resource-id.ts","../src/utils/sprites.ts","../src/utils/type-chart.ts"],"sourcesContent":["/** Enum of Berries (NAME - ID) */\nexport const BERRIES = {\n CHERI: 1,\n CHESTO: 2,\n PECHA: 3,\n RAWST: 4,\n ASPEAR: 5,\n LEPPA: 6,\n ORAN: 7,\n PERSIM: 8,\n LUM: 9,\n SITRUS: 10,\n FIGY: 11,\n WIKI: 12,\n MAGO: 13,\n AGUAV: 14,\n IAPAPA: 15,\n RAZZ: 16,\n BLUK: 17,\n NANAB: 18,\n WEPEAR: 19,\n PINAP: 20,\n POMEG: 21,\n KELPSY: 22,\n QUALOT: 23,\n HONDEW: 24,\n GREPA: 25,\n TAMATO: 26,\n CORNN: 27,\n MAGOST: 28,\n RABUTA: 29,\n NOMEL: 30,\n SPELON: 31,\n PAMTRE: 32,\n WATMEL: 33,\n DURIN: 34,\n BELUE: 35,\n OCCA: 36,\n PASSHO: 37,\n WACAN: 38,\n RINDO: 39,\n YACHE: 40,\n CHOPLE: 41,\n KEBIA: 42,\n SHUCA: 43,\n COBA: 44,\n PAYAPA: 45,\n TANGA: 46,\n CHARTI: 47,\n KASIB: 48,\n HABAN: 49,\n COLBUR: 50,\n BABIRI: 51,\n CHILAN: 52,\n LIECHI: 53,\n GANLON: 54,\n SALAC: 55,\n PETAYA: 56,\n APICOT: 57,\n LANSAT: 58,\n STARF: 59,\n ENIGMA: 60,\n MICLE: 61,\n CUSTAP: 62,\n JABOCA: 63,\n ROWAP: 64,\n KEE: 65,\n MARANGA: 66,\n HOPO: 67,\n ROSELI: 68,\n} as const;\n\n/** Enum of Berry Firmnesses (NAME - ID) */\nexport const BERRY_FIRMNESSES = {\n VERY_SOFT: 1,\n SOFT: 2,\n HARD: 3,\n VERY_HARD: 4,\n SUPER_HARD: 5,\n} as const;\n\nexport const BERRY_FLAVORS = {\n SPICY: 1,\n DRY: 2,\n SWEET: 3,\n BITTER: 4,\n SOUR: 5,\n} as const;\n","export const CONTEST_TYPES = {\n COOL: 1,\n BEAUTY: 2,\n CUTE: 3,\n SMART: 4,\n TOUGH: 5,\n} as const;\n","export const CURRENCIES = {\n POKE_DOLLAR: 1,\n COIN: 2,\n VOLCANIC_ASH: 3,\n POKE_COUPON: 4,\n BERRY_POWDER: 5,\n BATTLE_POINT: 6,\n SPHERE: 7,\n CASTLE_POINT: 8,\n WATT: 9,\n ATHLETE_POINT: 10,\n DREAM_POINT: 11,\n DREAM_WORLD_BERRY: 12,\n POKE_MILE: 13,\n FESTIVAL_COIN: 14,\n POKE_BEAN: 15,\n HOME_POINT: 16,\n MERIT_POINT: 17,\n LEAGUE_POINT: 18,\n BLUEBERRY_POINT: 19,\n} as const;\n","export const ENCOUNTER_METHODS = {\n WALK: 1,\n OLD_ROD: 2,\n GOOD_ROD: 3,\n SUPER_ROD: 4,\n SURF: 5,\n ROCK_SMASH: 6,\n HEADBUTT: 7,\n DARK_GRASS: 8,\n GRASS_SPOTS: 9,\n CAVE_SPOTS: 10,\n BRIDGE_SPOTS: 11,\n SUPER_ROD_SPOTS: 12,\n SURF_SPOTS: 13,\n YELLOW_FLOWERS: 14,\n PURPLE_FLOWERS: 15,\n RED_FLOWERS: 16,\n ROUGH_TERRAIN: 17,\n GIFT: 18,\n GIFT_EGG: 19,\n STATIC: 20,\n POKEFLUTE: 21,\n HEADBUTT_LOW: 22,\n HEADBUTT_NORMAL: 23,\n HEADBUTT_HIGH: 24,\n SQUIRT_BOTTLE: 25,\n WAILMER_PAIL: 26,\n SEAWEED: 27,\n ROAMING_GRASS: 28,\n ROAMING_WATER: 29,\n DEVON_SCOPE: 30,\n FEEBAS_TILE_FISHING: 31,\n ISLAND_SCAN: 32,\n SOS: 33,\n BUBBLING_SPOTS: 34,\n BERRY_TREES: 35,\n NPC_TRADE: 36,\n SOS_FROM_BUBBLING_SPOT: 37,\n OVERWORLD: 38,\n OVERWORLD_WATER: 39,\n OVERWORLD_FLYING: 40,\n OVERWORLD_SPECIAL: 41,\n OVERWORLD_FLYING_SPECIAL: 42,\n OVERWORLD_WATER_SPECIAL: 43,\n HORDE: 44,\n COLOSSEUM_BONUS_DISC_US: 45,\n COLOSSEUM_BONUS_DISC_JPN: 46,\n POKEMON_CHANNEL_PAL: 47,\n POKEMON_RANGER: 48,\n POKEMON_BATTLE_REVOLUTION: 49,\n NEW_YORK_POKECENTER_WISH_EGGS: 50,\n SNAG: 51,\n SNAG_REMATCH: 52,\n POKESPOT: 53,\n HIDDEN_GROTTO: 54,\n HONEY_TREE: 55,\n OVERWORLD_DIRT: 56,\n WANDERER: 57,\n WANDERER_WATER: 58,\n CHASE_WATER: 59,\n DYNAMAX_ADVENTURE: 60,\n MAX_RAID: 61,\n TRASH_CAN_AMBUSH: 62,\n RUSTLING_BUSH_AMBUSH: 63,\n CEILING_AMBUSH: 64,\n GROUND_AMBUSH: 65,\n SKY_AMBUSH: 66,\n /**\n * @deprecated Misspelled: the endpoint names this `headbutt-high`.\n * Use {@link ENCOUNTER_METHODS.HEADBUTT_HIGH}. Removed in 3.0.\n */\n HEADBUT_HIGH: 24,\n /**\n * @deprecated The endpoint names this `static` now.\n * Use {@link ENCOUNTER_METHODS.STATIC}. Removed in 3.0.\n */\n ONLY_ONE: 20,\n} as const;\n\nexport const ENCOUNTER_CONDITIONS = {\n SWARM: 1,\n TIME: 2,\n RADAR: 3,\n SLOT2: 4,\n RADIO: 5,\n SEASON: 6,\n STARTER: 7,\n TV_OPTION: 8,\n STORY_PROGRESS: 9,\n OTHER: 10,\n ITEM: 11,\n WEEKDAY: 12,\n FIRST_PARTY_POKEMON: 13,\n SPECIAL_ENCOUNTER: 14,\n TRADE: 15,\n COINS: 16,\n FRIEND_SAFARI_SLOT: 17,\n GREAT_MARSH_DAILY_SLOT: 18,\n HONEY_TREE_GROUP: 19,\n HEADBUTT_TREE: 20,\n BACKLOT: 21,\n BUG_CATCHING_CONTEST: 22,\n SAVE_DATA: 23,\n ALOLAN_DIGLETT_FOUND: 24,\n WEATHER: 25,\n JOHTO_SAFARI_BLOCKS: 26,\n MAX_DEN_RARITY: 27,\n MAX_DEN_RATING: 28,\n BERRY_TREE_TYPE: 29,\n TRASH_CAN_TYPE: 30,\n} as const;\n\nexport const ENCOUNTER_CONDITION_VALUES = {\n SWARM_YES: 1,\n SWARM_NO: 2,\n TIME_MORNING: 3,\n TIME_DAY: 4,\n TIME_NIGHT: 5,\n RADAR_ON: 6,\n RADAR_OFF: 7,\n SLOT2_NONE: 8,\n SLOT2_RUBY: 9,\n SLOT2_SAPPHIRE: 10,\n SLOT2_EMERALD: 11,\n SLOT2_FIRERED: 12,\n SLOT2_LEAFGREEN: 13,\n RADIO_OFF: 14,\n RADIO_HOENN: 15,\n RADIO_SINNOH: 16,\n SEASON_SPRING: 17,\n SEASON_SUMMER: 18,\n SEASON_AUTUMN: 19,\n SEASON_WINTER: 20,\n STARTER_BULBASAUR: 21,\n STARTER_SQUIRTLE: 22,\n STARTER_CHARMANDER: 23,\n STARTER_CHESPIN: 24,\n STARTER_FENNEKIN: 25,\n STARTER_FROAKIE: 26,\n TV_OPTION_BLUE: 27,\n TV_OPTION_RED: 28,\n STORY_PROGRESS_AWAKENED_BEASTS: 29,\n STORY_PROGRESS_BEAT_GALACTIC_CORONET: 30,\n STORY_PROGRESS_OAK_ETERNA_CITY: 31,\n STORY_PROGRESS_VERMILION_COPYCAT: 32,\n STORY_PROGRESS_MET_TORNADUS_THUNDURUS: 33,\n STORY_PROGRESS_BEAT_ELITE_FOUR_ROUND_TWO: 34,\n STORY_PROGRESS_HALL_OF_FAME: 35,\n STORY_PROGRESS_NONE: 36,\n STORY_PROGRESS_NATIONAL_DEX: 37,\n OTHER_NONE: 38,\n OTHER_SNORLAX_11_BEAT_LEAGUE: 39,\n OTHER_VIRTUAL_CONSOLE: 40,\n STORY_PROGRESS_CURE_ELDRITCH_NIGHTMARES: 41,\n OTHER_TALK_TO_CYNTHIAS_GRANDMOTHER: 42,\n ITEM_NONE: 43,\n ITEM_ADAMANT_ORB: 44,\n ITEM_LUSTROUS_ORB: 45,\n ITEM_HELIX_FOSSIL: 46,\n ITEM_DOME_FOSSIL: 47,\n ITEM_OLD_AMBER: 48,\n ITEM_ROOT_FOSSIL: 49,\n ITEM_CLAW_FOSSIL: 50,\n STORY_PROGRESS_DEFEAT_JUPITER: 51,\n STORY_PROGRESS_BEAT_TEAM_GALACTIC_IRON_ISLAND: 52,\n OTHER_CORRECT_PASSWORD: 53,\n STORY_PROGRESS_ZEPHYR_BADGE: 54,\n STORY_PROGRESS_BEAT_RED: 55,\n OTHER_RECEIVED_KANTO_STARTER: 56,\n STORY_PROGRESS_RECEIVE_TM_FROM_CLAIRE: 57,\n OTHER_REGIROCK_REGICE_REGISTEEL_IN_PARTY: 58,\n WEEKDAY_SUNDAY: 59,\n WEEKDAY_MONDAY: 60,\n WEEKDAY_TUESDAY: 61,\n WEEKDAY_WEDNESDAY: 62,\n WEEKDAY_THURSDAY: 63,\n WEEKDAY_FRIDAY: 64,\n WEEKDAY_SATURDAY: 65,\n FIRST_PARTY_POKEMON_HIGH_FRIENDSHIP: 66,\n STORY_PROGRESS_DEFEAT_MARS: 67,\n ITEM_ODD_KEYSTONE: 68,\n OTHER_TALKED_TO_32_PEOPLE_UNDERGROUND: 69,\n STORY_PROGRESS_RETURNED_MACHINE_PART: 70,\n OTHER_EVENT_ARCEUS_IN_PARTY: 71,\n SPECIAL_ENCOUNTER_COULDNT_CAPTURE_BEFORE: 72,\n ITEM_ICE_KEY: 73,\n ITEM_IRON_KEY: 74,\n STORY_PROGRESS_JUNIPER_CAVE_OF_BEING: 75,\n ITEM_LUNAR_WING: 76,\n STORY_PROGRESS_QUAKE_BADGE: 77,\n ITEM_LIGHT_STONE: 78,\n ITEM_DARK_STONE: 79,\n OTHER_CAPTURED_RESHIRAM_OR_ZEKROM: 80,\n DEFEATED_GHETSIS: 81,\n OTHER_FOUND_11_TIMES_ROAMING: 82,\n TIME_MINUTE_00_TO_19: 83,\n TIME_MINUTE_20_TO_39: 84,\n TIME_MINUTE_40_TO_59: 85,\n TIME_04_00_TO_19_59: 86,\n TIME_20_00_TO_21_59: 87,\n TIME_21_00_TO_03_59: 88,\n ITEM_TIDAL_BELL: 89,\n ITEM_CLEAR_BELL: 90,\n STORY_PROGRESS_DEFEATED_GROUDON_OR_KYOGRE: 91,\n OTHER_UXIE_MESPRIT_AZELF_IN_PARTY: 92,\n OTHER_NICKNAMED_COLD_ITEM_REGICE_REGIROCK_REGISTEEL3: 93,\n OTHER_DIALGA_OR_PALKIA_IN_PARTY: 94,\n OTHER_CASTFORM_IN_PARTY: 95,\n OTHER_LEVEL_100_POKEMON_IN_PARTY: 96,\n OTHER_TORNADUS_THUNDURUS_IN_PARTY: 97,\n OTHER_RESHIRAM_ZEKROM_IN_PARTY: 98,\n OTHER_CAPTURED_ALL_ULTRA_BEASTS: 99,\n STORY_PROGRESS_FINISHED_LOOKER_SIDEQUEST: 100,\n STORY_PROGRESS_BEAT_OLIVIAS_TRIAL: 101,\n OTHER_RAIKOU_ENTEI_IN_PARTY: 102,\n OTHER_GROUDON_KYOGRE_IN_PARTY: 103,\n OTHER_DIALGA_PALKIA_IN_PARTY: 104,\n OTHER_SCAN_QR_CODE: 105,\n OTHER_CAUGHT_ARTICUNO: 106,\n OTHER_CAUGHT_ZAPDOS: 107,\n OTHER_CAUGHT_MOLTRES: 108,\n TRADE_TOGEPI_OR_TOGETIC: 109,\n TRADE_TRAPINCH: 110,\n TRADE_SURSKIT: 111,\n TRADE_WOOPER: 112,\n STORY_PROGRESS_CATCH_ALL_SHADOW_POKEMON: 113,\n OTHER_COMPLETE_MT_BATTLE: 114,\n COINS_180: 115,\n COINS_500: 116,\n COINS_1200: 117,\n COINS_2800: 118,\n COINS_5500: 119,\n COINS_9999: 120,\n COINS_120: 121,\n COINS_750: 122,\n COINS_2500: 123,\n COINS_4600: 124,\n COINS_6500: 125,\n COINS_230: 126,\n COINS_1000: 127,\n COINS_2680: 128,\n COINS_3333: 129,\n COINS_6666: 130,\n COINS_200: 131,\n COINS_700: 132,\n COINS_2100: 133,\n COINS_100: 134,\n COINS_800: 135,\n COINS_1500: 136,\n COINS_2222: 137,\n COINS_5555: 138,\n COINS_8888: 139,\n COINS_150: 140,\n COINS_620: 141,\n COINS_2880: 142,\n COINS_5400: 143,\n COINS_8300: 144,\n TRADE_ABRA: 145,\n TRADE_NIDORAN_M: 146,\n TRADE_NIDORINO: 147,\n TRADE_SLOWBRO: 148,\n TRADE_POLIWHIRL: 149,\n TRADE_SPEAROW: 150,\n TRADE_RAICHU: 151,\n TRADE_VENONAT: 152,\n TRADE_PONYTA: 153,\n TRADE_CLEFAIRY: 154,\n TRADE_CUBONE: 155,\n TRADE_LICKITUNG: 156,\n TRADE_TANGELA: 157,\n TRADE_GOLDUCK: 158,\n TRADE_GROWLITHE: 159,\n TRADE_KANGASKHAN: 160,\n TRADE_BELLSPROUT: 161,\n TRADE_DROWZEE: 162,\n TRADE_KRABBY: 163,\n TRADE_DRAGONAIR: 164,\n TRADE_CHANSEY: 165,\n TRADE_GLOOM: 166,\n TRADE_HAUNTER: 167,\n TRADE_DUGTRIO: 168,\n TRADE_SLAKOTH: 169,\n TRADE_PIKACHU: 170,\n TRADE_BELLOSSOM: 171,\n TRADE_RALTS: 172,\n TRADE_VOLBEAT: 173,\n TRADE_BAGON: 174,\n TRADE_SKITTY: 175,\n FRIEND_SAFARI_SLOT_1: 176,\n FRIEND_SAFARI_SLOT_2: 177,\n FRIEND_SAFARI_SLOT_3: 178,\n ITEM_SKULL_FOSSIL: 179,\n ITEM_ARMOR_FOSSIL: 180,\n GREAT_MARSH_DAILY_SLOT_NONE: 181,\n GREAT_MARSH_DAILY_SLOT_1_OF_32: 182,\n GREAT_MARSH_DAILY_SLOT_2_OF_32: 183,\n GREAT_MARSH_DAILY_SLOT_3_OF_32: 184,\n GREAT_MARSH_DAILY_SLOT_5_OF_32: 185,\n STORY_PROGRESS_BEFORE_NATIONAL_DEX: 186,\n GREAT_MARSH_DAILY_SLOT_4_OF_32: 187,\n GREAT_MARSH_DAILY_SLOT_15_OF_32: 188,\n HONEY_TREE_GROUP_A: 189,\n HONEY_TREE_GROUP_B: 190,\n HONEY_TREE_GROUP_C: 191,\n HEADBUTT_TREE_COMMON: 192,\n HEADBUTT_TREE_RARE: 193,\n HEADBUTT_TREE_SECRET: 194,\n TRADE_COTTONEE: 195,\n TRADE_PETILIL: 196,\n TRADE_EMOLGA: 197,\n TRADE_MANTINE: 198,\n TRADE_DITTO: 199,\n TRADE_EXCADRILL: 200,\n TRADE_HIPPOWDON: 201,\n BACKLOT_NOT_MENTIONED: 202,\n BACKLOT_MENTIONED: 203,\n BUG_CATCHING_CONTEST_NO: 204,\n BUG_CATCHING_CONTEST_YES: 205,\n SAVE_DATA_FROM_LETS_GO_PIKACHU: 206,\n SAVE_DATA_FROM_LETS_GO_EEVEE: 207,\n ITEM_FOSSILIZED_BIRD: 208,\n ITEM_FOSSILIZED_DRAKE: 209,\n ITEM_FOSSILIZED_DINO: 210,\n ITEM_FOSSILIZED_FISH: 211,\n STORY_PROGRESS_MASTER_DOJO_COMPLETE_FIRST_TRIAL: 212,\n STORY_PROGRESS_MASTER_DOJO_COMPLETE_THIRD_TRIAL: 213,\n ALOLAN_DIGLETT_FOUND_5: 214,\n ALOLAN_DIGLETT_FOUND_10: 215,\n ALOLAN_DIGLETT_FOUND_20: 216,\n ALOLAN_DIGLETT_FOUND_30: 217,\n ALOLAN_DIGLETT_FOUND_40: 218,\n ALOLAN_DIGLETT_FOUND_50: 219,\n ALOLAN_DIGLETT_FOUND_75: 220,\n ALOLAN_DIGLETT_FOUND_100: 221,\n ALOLAN_DIGLETT_FOUND_150: 222,\n STARTER_GROOKEY: 223,\n STARTER_SCORBUNNY: 224,\n STARTER_SOBBLE: 225,\n STORY_PROGRESS_SAVE_VILLAGE_FROM_GLASTRIER_SPECTRIER: 226,\n STORY_PROGRESS_CATCH_FIVE_ULTRA_BEASTS: 227,\n TRADE_BUNNELBY: 228,\n TRADE_MEOWTH_GALAR: 229,\n TRADE_MINCCINO: 230,\n TRADE_TOXEL: 231,\n TRADE_MARACTUS: 232,\n TRADE_YAMASK_GALAR: 233,\n TRADE_VANILLISH: 234,\n TRADE_OBSTAGOON: 235,\n TRADE_FROSMOTH: 236,\n TRADE_FARFETCHD_GALAR: 237,\n TRADE_CORSOLA_GALAR: 238,\n TRADE_PONYTA_GALAR: 239,\n TRADE_MR_MIME_GALAR: 240,\n TRADE_DARUMAKA_GALAR: 241,\n TRADE_ZIGZAGOON_GALAR: 242,\n TRADE_STUNFISK_GALAR: 243,\n TRADE_WEEZING_GALAR: 244,\n TRADE_EXEGGUTOR: 245,\n TRADE_MAROWAK: 246,\n WEATHER_NORMAL: 247,\n WEATHER_OVERCAST: 248,\n WEATHER_RAINING: 249,\n WEATHER_THUNDERSTORM: 250,\n WEATHER_SNOWING: 251,\n WEATHER_SNOWSTORM: 252,\n WEATHER_SANDSTORM: 253,\n WEATHER_INTENSE_SUN: 254,\n WEATHER_FOG: 255,\n STORY_PROGRESS_BEFORE_HALL_OF_FAME: 256,\n JOHTO_SAFARI_BLOCKS_INACTIVE: 257,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_2: 258,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_3: 259,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_4: 260,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_5: 261,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_6: 262,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_10: 263,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_12: 264,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_14: 265,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_15: 266,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_24: 267,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_28: 268,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_35: 269,\n JOHTO_SAFARI_BLOCKS_PLAINS_MIN_49: 270,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_3: 271,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_4: 272,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_5: 273,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_8: 274,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_10: 275,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_14: 276,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_15: 277,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_18: 278,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_20: 279,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_28: 280,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_35: 281,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_42: 282,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_49: 283,\n JOHTO_SAFARI_BLOCKS_FOREST_MIN_56: 284,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_3: 285,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_4: 286,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_5: 287,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_6: 288,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_8: 289,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_10: 290,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_15: 291,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_21: 292,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_24: 293,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_28: 294,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_35: 295,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_42: 296,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_49: 297,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_56: 298,\n JOHTO_SAFARI_BLOCKS_PEAK_MIN_63: 299,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_2: 300,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_3: 301,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_4: 302,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_5: 303,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_6: 304,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_7: 305,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_8: 306,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_9: 307,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_10: 308,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_12: 309,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_13: 310,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_14: 311,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_15: 312,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_16: 313,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_18: 314,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_20: 315,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_24: 316,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_28: 317,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_35: 318,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_42: 319,\n JOHTO_SAFARI_BLOCKS_WATER_MIN_49: 320,\n ITEM_COVER_FOSSIL: 321,\n ITEM_PLUME_FOSSIL: 322,\n OTHER_GIRATINA_NOT_CAUGHT_IN_DISTORTION_WORLD: 323,\n OTHER_FIND_50_CAVERN_FOOTPRINTS: 324,\n OTHER_FIND_50_GRASSLAND_FOOTPRINTS: 325,\n OTHER_FIND_50_IRON_WILL_FOOTPRINTS: 326,\n OTHER_REGIROCK_REGICE_REGISTEEL_REGIELEKI_REGIDRAGO_IN_PARTY: 327,\n OTHER_CHOOSE_REGIELEKI_PATTERN: 328,\n OTHER_CHOOSE_REGIDRAGO_PATTERN: 329,\n OTHER_GROW_ICEROOT_CARROT: 330,\n OTHER_GROW_SHADEROOT_CARROT: 331,\n OTHER_TALKED_TO_32_PEOPLE: 332,\n OTHER_EAT_CURRY_WITH_COBALION_TERRAKION_VIRIZION: 333,\n ITEM_REINS_OF_UNITY: 334,\n OTHER_WITNESS_GALARIAN_BIRD_FIGHT: 335,\n MAX_DEN_RARITY_COMMON: 336,\n MAX_DEN_RARITY_RARE: 337,\n MAX_DEN_RATING_1_STAR: 338,\n MAX_DEN_RATING_2_STAR: 339,\n MAX_DEN_RATING_3_STAR: 340,\n MAX_DEN_RATING_4_STAR: 341,\n MAX_DEN_RATING_5_STAR: 342,\n MAX_DEN_RARITY_SPECIAL: 343,\n BERRY_TREE_TYPE_RED: 344,\n BERRY_TREE_TYPE_BLUE: 345,\n BERRY_TREE_TYPE_PURPLE: 346,\n BERRY_TREE_TYPE_GREEN: 347,\n BERRY_TREE_TYPE_YELLOW: 348,\n BERRY_TREE_TYPE_PINK: 349,\n TRASH_CAN_TYPE_DAILY: 350,\n TRASH_CAN_TYPE_TUESDAY: 351,\n TRASH_CAN_TYPE_THURSDAY: 352,\n TRADE_NIDORAN_F: 353,\n TRADE_NIDORINA: 354,\n TRADE_MACHOP: 355,\n TRADE_BUIZEL: 356,\n TRADE_MEDICHAM: 357,\n TRADE_FINNEON: 358,\n TRADE_FORRETRESS: 359,\n TRADE_BONSLY: 360,\n TRADE_ANY_POKEMON: 361,\n /**\n * @deprecated Misspelled: the endpoint names this `other-snorlax-11-beat-league`.\n * Use {@link ENCOUNTER_CONDITION_VALUES.OTHER_SNORLAX_11_BEAT_LEAGUE}. Removed in 3.0.\n */\n OTHER_SNORLAX_LL_BEAT_LEAGUE: 39,\n /**\n * @deprecated Misspelled: the endpoint names this `radio-hoenn`.\n * Use {@link ENCOUNTER_CONDITION_VALUES.RADIO_HOENN}. Removed in 3.0.\n */\n RADIO_HOEN: 15,\n /**\n * @deprecated Misspelled: the endpoint names this `slot2-sapphire`.\n * Use {@link ENCOUNTER_CONDITION_VALUES.SLOT2_SAPPHIRE}. Removed in 3.0.\n */\n SLOT2_SAPHIRE: 10,\n /**\n * @deprecated The endpoint names this `story-progress-vermilion-copycat` now.\n * Use {@link ENCOUNTER_CONDITION_VALUES.STORY_PROGRESS_VERMILION_COPYCAT}. Removed in 3.0.\n */\n STORY_PROGRESS_OAK_VERMILION_COPYCAT: 32,\n /**\n * @deprecated Misspelled: the endpoint names this `season-autumn`.\n * Use {@link ENCOUNTER_CONDITION_VALUES.SEASON_AUTUMN}. Removed in 3.0.\n */\n SWASON_AUTUMN: 19,\n} as const;\n","/**\n * Endpoints of the PokéAPI\n */\nexport const ENDPOINTS = {\n BERRY: \"/berry\",\n BERRY_FIRMNESS: \"/berry-firmness\",\n BERRY_FLAVOR: \"/berry-flavor\",\n CONTEST_TYPE: \"/contest-type\",\n CONTEST_EFFECT: \"/contest-effect\",\n SUPER_CONTEST_EFFECT: \"/super-contest-effect\",\n CURRENCY: \"/currency\",\n ENCOUNTER_METHOD: \"/encounter-method\",\n ENCOUNTER_CONDITION: \"/encounter-condition\",\n ENCOUNTER_CONDITION_VALUE: \"/encounter-condition-value\",\n EVOLUTION_CHAIN: \"/evolution-chain\",\n EVOLUTION_TRIGGER: \"/evolution-trigger\",\n GENERATION: \"/generation\",\n POKEDEX: \"/pokedex\",\n VERSION: \"/version\",\n VERSION_GROUP: \"/version-group\",\n ITEM: \"/item\",\n ITEM_ATTRIBUTE: \"/item-attribute\",\n ITEM_CATEGORY: \"/item-category\",\n ITEM_FLING_EFFECT: \"/item-fling-effect\",\n ITEM_POCKET: \"/item-pocket\",\n LOCATION: \"/location\",\n LOCATION_AREA: \"/location-area\",\n PALPARK_AREA: \"/pal-park-area\",\n REGION: \"/region\",\n MACHINE: \"/machine\",\n MOVE: \"/move\",\n MOVE_AILMENT: \"/move-ailment\",\n MOVE_BATTLE_STYLE: \"/move-battle-style\",\n MOVE_CATEGORY: \"/move-category\",\n MOVE_DAMAGE_CLASS: \"/move-damage-class\",\n MOVE_LEARN_METHOD: \"/move-learn-method\",\n MOVE_TARGET: \"/move-target\",\n ABILITY: \"/ability\",\n CHARACTERISTIC: \"/characteristic\",\n EGG_GROUP: \"/egg-group\",\n GENDER: \"/gender\",\n GROWTH_RATE: \"/growth-rate\",\n NATURE: \"/nature\",\n POKEATHLON_STAT: \"/pokeathlon-stat\",\n POKEMON: \"/pokemon\",\n POKEMON_COLOR: \"/pokemon-color\",\n POKEMON_FORM: \"/pokemon-form\",\n POKEMON_HABITAT: \"/pokemon-habitat\",\n POKEMON_SHAPE: \"/pokemon-shape\",\n POKEMON_SPECIES: \"/pokemon-species\",\n STAT: \"/stat\",\n TYPE: \"/type\",\n LANGUAGE: \"/language\",\n} as const;\n\ntype ObjectValue<T> = T[keyof T];\nexport type Endpoint = ObjectValue<typeof ENDPOINTS>;\n","export const EVOLUTION_TRIGGERS = {\n LEVEL_UP: 1,\n TRADE: 2,\n USE_ITEM: 3,\n SHED: 4,\n SPIN: 5,\n TOWER_OF_DARKNESS: 6,\n TOWER_OF_WATERS: 7,\n THREE_CRITICAL_HITS: 8,\n TAKE_DAMAGE: 9,\n OTHER: 10,\n AGILE_STYLE_MOVE: 11,\n STRONG_STYLE_MOVE: 12,\n RECOIL_DAMAGE: 13,\n USE_MOVE: 14,\n THREE_DEFEATED_BISHARP: 15,\n GIMMIGHOUL_COINS: 16,\n /**\n * @deprecated Misspelled: the endpoint names this trigger `tower-of-waters`.\n * Use {@link EVOLUTION_TRIGGERS.TOWER_OF_WATERS}. Removed in 3.0.\n */\n TOWER_OF_WATER: 7,\n} as const;\n","export const GENERATIONS = {\n GENERATION_I: 1,\n GENERATION_II: 2,\n GENERATION_III: 3,\n GENERATION_IV: 4,\n GENERATION_V: 5,\n GENERATION_VI: 6,\n GENERATION_VII: 7,\n GENERATION_VIII: 8,\n GENERATION_IX: 9,\n} as const;\n\n/**\n * ## Generation Name\n * A generation as the PokéAPI names it, which is what a\n * `NamedAPIResource<Generation>` carries and what the helpers that resolve a\n * resource's past state are given.\n *\n * Written out rather than derived from {@link GENERATIONS}: turning\n * `GENERATION_VIII` into `generation-viii` in the type system takes a recursive\n * template literal, and the set is closed and nine long.\n */\nexport type GenerationName =\n | \"generation-i\"\n | \"generation-ii\"\n | \"generation-iii\"\n | \"generation-iv\"\n | \"generation-v\"\n | \"generation-vi\"\n | \"generation-vii\"\n | \"generation-viii\"\n | \"generation-ix\";\n\nexport const POKEDEXES = {\n NATIONAL: 1,\n KANTO: 2,\n ORIGINAL_JOHTO: 3,\n HOENN: 4,\n ORIGINAL_SINNOH: 5,\n EXTENDED_SINNOH: 6,\n UPDATED_JOHTO: 7,\n ORIGINAL_UNOVA: 8,\n UPDATED_UNOVA: 9,\n CONQUEST_GALLERY: 11,\n KALOS_CENTRAL: 12,\n KALOS_COASTAL: 13,\n KALOS_MOUNTAIN: 14,\n UPDATED_HOENN: 15,\n ORIGINAL_ALOLA: 16,\n ORIGINAL_MELEMELE: 17,\n ORIGINAL_AKALA: 18,\n ORIGINAL_ULAULA: 19,\n ORIGINAL_PONI: 20,\n UPDATED_ALOLA: 21,\n UPDATED_MELEMELE: 22,\n UPDATED_AKALA: 23,\n UPDATED_ULAULA: 24,\n UPDATED_PONI: 25,\n LETSGO_KANTO: 26,\n GALAR: 27,\n ISLE_OF_ARMOR: 28,\n CROWN_TUNDRA: 29,\n HISUI: 30,\n PALDEA: 31,\n KITAKAMI: 32,\n BLUEBERRY: 33,\n LUMIOSE_CITY: 34,\n HYPERSPACE: 35,\n CHAMPIONS: 36,\n /**\n * @deprecated Misspelled: the endpoint names this `kalos-mountain`.\n * Use {@link POKEDEXES.KALOS_MOUNTAIN}. Removed in 3.0.\n */\n KALOS_MONTAIN: 14,\n /**\n * @deprecated The endpoint names this `letsgo-kanto` now.\n * Use {@link POKEDEXES.LETSGO_KANTO}. Removed in 3.0.\n */\n UPDATED_KANTO: 26,\n} as const;\n\nexport const VERSIONS = {\n RED: 1,\n BLUE: 2,\n YELLOW: 3,\n GOLD: 4,\n SILVER: 5,\n CRYSTAL: 6,\n RUBY: 7,\n SAPPHIRE: 8,\n EMERALD: 9,\n FIRERED: 10,\n LEAFGREEN: 11,\n DIAMOND: 12,\n PEARL: 13,\n PLATINUM: 14,\n HEARTGOLD: 15,\n SOULSILVER: 16,\n BLACK: 17,\n WHITE: 18,\n COLOSSEUM: 19,\n XD: 20,\n BLACK_2: 21,\n WHITE_2: 22,\n X: 23,\n Y: 24,\n OMEGA_RUBY: 25,\n ALPHA_SAPPHIRE: 26,\n SUN: 27,\n MOON: 28,\n ULTRA_SUN: 29,\n ULTRA_MOON: 30,\n LETS_GO_PIKACHU: 31,\n LETS_GO_EEVEE: 32,\n SWORD: 33,\n SHIELD: 34,\n THE_ISLE_OF_ARMOR_SWORD: 35,\n THE_CROWN_TUNDRA_SWORD: 36,\n BRILLIANT_DIAMOND: 37,\n SHINING_PEARL: 38,\n LEGENDS_ARCEUS: 39,\n SCARLET: 40,\n VIOLET: 41,\n THE_TEAL_MASK_SCARLET: 42,\n THE_INDIGO_DISK_SCARLET: 43,\n RED_JAPAN: 44,\n GREEN_JAPAN: 45,\n BLUE_JAPAN: 46,\n LEGENDS_ZA: 47,\n MEGA_DIMENSION: 48,\n CHAMPIONS: 49,\n THE_ISLE_OF_ARMOR_SHIELD: 50,\n THE_CROWN_TUNDRA_SHIELD: 51,\n THE_TEAL_MASK_VIOLET: 52,\n THE_INDIGO_DISK_VIOLET: 53,\n /**\n * @deprecated The endpoint names this `the-crown-tundra-sword` now.\n * Use {@link VERSIONS.THE_CROWN_TUNDRA_SWORD}. Removed in 3.0.\n */\n THE_CROWN_TUNDRA: 36,\n /**\n * @deprecated The endpoint names this `the-isle-of-armor-sword` now.\n * Use {@link VERSIONS.THE_ISLE_OF_ARMOR_SWORD}. Removed in 3.0.\n */\n THE_ISLE_OF_ARMOR: 35,\n} as const;\n\nexport const VERSION_GROUPS = {\n RED_BLUE: 1,\n YELLOW: 2,\n GOLD_SILVER: 3,\n CRYSTAL: 4,\n RUBY_SAPPHIRE: 5,\n EMERALD: 6,\n FIRERED_LEAFGREEN: 7,\n DIAMOND_PEARL: 8,\n PLATINUM: 9,\n HEARTGOLD_SOULSILVER: 10,\n BLACK_WHITE: 11,\n COLOSSEUM: 12,\n XD: 13,\n BLACK_2_WHITE_2: 14,\n X_Y: 15,\n OMEGA_RUBY_ALPHA_SAPPHIRE: 16,\n SUN_MOON: 17,\n ULTRA_SUN_ULTRA_MOON: 18,\n LETS_GO_PIKACHU_LETS_GO_EEVEE: 19,\n SWORD_SHIELD: 20,\n THE_ISLE_OF_ARMOR: 21,\n THE_CROWN_TUNDRA: 22,\n BRILLIANT_DIAMOND_SHINING_PEARL: 23,\n LEGENDS_ARCEUS: 24,\n SCARLET_VIOLET: 25,\n THE_TEAL_MASK: 26,\n THE_INDIGO_DISK: 27,\n RED_GREEN_JAPAN: 28,\n BLUE_JAPAN: 29,\n LEGENDS_ZA: 30,\n MEGA_DIMENSION: 31,\n CHAMPIONS: 32,\n /**\n * @deprecated The endpoint names this `brilliant-diamond-shining-pearl` now.\n * Use {@link VERSION_GROUPS.BRILLIANT_DIAMOND_SHINING_PEARL}. Removed in 3.0.\n */\n BRILLIANT_DIAMOND_AND_SHINING_PEARL: 23,\n /**\n * @deprecated The endpoint names this `lets-go-pikachu-lets-go-eevee` now.\n * Use {@link VERSION_GROUPS.LETS_GO_PIKACHU_LETS_GO_EEVEE}. Removed in 3.0.\n */\n LETS_GO: 19,\n} as const;\n","export const ITEM_ATTRIBUTES = {\n COUNTABLE: 1,\n CONSUMABLE: 2,\n USABLE_OVERWORLD: 3,\n USABLE_IN_BATTLE: 4,\n HOLDABLE: 5,\n HOLDABLE_PASSIVE: 6,\n HOLDABLE_ACTIVE: 7,\n UNDERGROUND: 8,\n} as const;\n\nexport const ITEM_CATEGORIES = {\n STAT_BOOSTS: 1,\n EFFORT_DROP: 2,\n MEDICINE: 3,\n OTHER: 4,\n IN_A_PINCH: 5,\n PICKY_HEALING: 6,\n TYPE_PROTECTION: 7,\n BAKING_ONLY: 8,\n COLLECTIBLES: 9,\n EVOLUTION: 10,\n SPELUNKING: 11,\n HELD_ITEMS: 12,\n CHOICE: 13,\n EFFORT_TRAINING: 14,\n BAD_HELD_ITEMS: 15,\n TRAINING: 16,\n PLATES: 17,\n SPECIES_SPECIFIC: 18,\n TYPE_ENHANCEMENT: 19,\n EVENT_ITEMS: 20,\n GAMEPLAY: 21,\n PLOT_ADVANCEMENT: 22,\n UNUSED: 23,\n LOOT: 24,\n ALL_MAIL: 25,\n VITAMINS: 26,\n HEALING: 27,\n PP_RECOVERY: 28,\n REVIVAL: 29,\n STATUS_CURES: 30,\n MULCH: 32,\n SPECIAL_BALLS: 33,\n STANDARD_BALLS: 34,\n DEX_COMPLETION: 35,\n SCARVES: 36,\n ALL_MACHINES: 37,\n FLUTES: 38,\n APRICORN_BALLS: 39,\n APRICORN_BOX: 40,\n DATA_CARDS: 41,\n JEWELS: 42,\n MIRACLE_SHOOTER: 43,\n MEGA_STONES: 44,\n MEMORIES: 45,\n Z_CRYSTALS: 46,\n SPECIES_CANDIES: 47,\n CATCHING_BONUS: 48,\n DYNAMAX_CRYSTALS: 49,\n NATURE_MINTS: 50,\n CURRY_INGREDIENTS: 51,\n TERA_SHARD: 52,\n SANDWICH_INGREDIENTS: 53,\n TM_MATERIALS: 54,\n PICNIC: 55,\n /**\n * @deprecated Misspelled: the endpoint names this `dynamax-crystals`.\n * Use {@link ITEM_CATEGORIES.DYNAMAX_CRYSTALS}. Removed in 3.0.\n */\n DYNAMAX_CRISTALS: 49,\n} as const;\n\nexport const ITEM_FLING_EFFECTS = {\n BADLY_POISON: 1,\n BURN: 2,\n BERRY_EFFECT: 3,\n HERB_EFFECT: 4,\n PARALYZE: 5,\n POISON: 6,\n FLINCH: 7,\n} as const;\n\nexport const ITEM_POCKETS = {\n MISC: 1,\n MEDICINE: 2,\n POKEBALLS: 3,\n MACHINES: 4,\n BERRIES: 5,\n MAIL: 6,\n BATTLE: 7,\n KEY: 8,\n} as const;\n","export const REGIONS = {\n KANTO: 1,\n JOHTO: 2,\n HOENN: 3,\n SINNOH: 4,\n UNOVA: 5,\n KALOS: 6,\n ALOLA: 7,\n GALAR: 8,\n HISUI: 9,\n PALDEA: 10,\n ORRE: 11,\n} as const;\n\nexport const PAL_PARK_AREAS = {\n FOREST: 1,\n FIELD: 2,\n MOUNTAIN: 3,\n POND: 4,\n SEA: 5,\n} as const;\n","export const MOVE_AILMENTS = {\n UNKNOWN: -1,\n NONE: 0,\n PARALYSIS: 1,\n SLEEP: 2,\n FREEZE: 3,\n BURN: 4,\n POISON: 5,\n CONFUSION: 6,\n INFATUATION: 7,\n TRAP: 8,\n NIGHTMARE: 9,\n TORMENT: 12,\n DISABLE: 13,\n YAWN: 14,\n HEAL_BLOCK: 15,\n NO_TYPE_IMMUNITY: 17,\n LEECH_SEED: 18,\n EMBARGO: 19,\n PERISH_SONG: 20,\n INGRAIN: 21,\n SILENCE: 24,\n TAR_SHOT: 42,\n PROTECT: 43,\n} as const;\n\nexport const MOVE_BATTLE_STYLES = {\n ATTACK: 1,\n DEFENSE: 2,\n SUPPORT: 3,\n} as const;\n\nexport const MOVE_CATEGORIES = {\n DAMAGE: 0,\n AILMENT: 1,\n NET_GOOD_STATS: 2,\n HEAL: 3,\n DAMAGE_AILMENT: 4,\n SWAGGER: 5,\n DAMAGE_LOWER: 6,\n DAMAGE_RAISE: 7,\n DAMAGE_HEAL: 8,\n OHKO: 9,\n WHOLE_FIELD_EFFECT: 10,\n FIELD_EFFECT: 11,\n FORCE_SWITCH: 12,\n UNIQUE: 13,\n} as const;\n\nexport const MOVE_DAMAGE_CLASSES = {\n STATUS: 1,\n PHYSICAL: 2,\n SPECIAL: 3,\n} as const;\n\nexport const MOVE_LEARN_METHODS = {\n LEVEL_UP: 1,\n EGG: 2,\n TUTOR: 3,\n MACHINE: 4,\n STADIUM_SURFING_PIKACHU: 5,\n LIGHT_BALL_EGG: 6,\n COLOSSEUM_PURIFICATION: 7,\n XD_SHADOW: 8,\n XD_PURIFICATION: 9,\n FORM_CHANGE: 10,\n ZYGARDE_CUBE: 11,\n TRAIN: 12,\n} as const;\n\nexport const MOVE_TARGETS = {\n SPECIFIC_MOVE: 1,\n SELECTED_POKEMON_ME_FIRST: 2,\n ALLY: 3,\n USERS_FIELD: 4,\n USER_OR_ALLY: 5,\n OPPONENTS_FIELD: 6,\n USER: 7,\n RANDOM_OPPONENT: 8,\n ALL_OTHER_POKEMON: 9,\n SELECTED_POKEMON: 10,\n ALL_OPPONENTS: 11,\n ENTIRE_FIELD: 12,\n USER_AND_ALLIES: 13,\n ALL_POKEMON: 14,\n ALL_ALLIES: 15,\n FAINTING_POKEMON: 16,\n /**\n * @deprecated Misspelled: the endpoint names this `user-and-allies`.\n * Use {@link MOVE_TARGETS.USER_AND_ALLIES}. Removed in 3.0.\n */\n USER_AND_ALIES: 13,\n} as const;\n","export const EGG_GROUPS = {\n MONSTER: 1,\n WATER1: 2,\n BUG: 3,\n FLYING: 4,\n GROUND: 5,\n FAIRY: 6,\n PLANT: 7,\n HUMANSHAPE: 8,\n WATER3: 9,\n MINERAL: 10,\n INDETERMINATE: 11,\n WATER2: 12,\n DITTO: 13,\n DRAGON: 14,\n NO_EGGS: 15,\n} as const;\n\nexport const GENDERS = {\n FEMALE: 1,\n MALE: 2,\n GENDERLESS: 3,\n} as const;\n\nexport const GROWTH_RATES = {\n SLOW: 1,\n MEDIUM: 2,\n FAST: 3,\n MEDIUM_SLOW: 4,\n SLOW_THEN_VERY_FAST: 5,\n FAST_THEN_VERY_SLOW: 6,\n} as const;\n\nexport const NATURES = {\n HARDY: 1,\n BOLD: 2,\n MODEST: 3,\n CALM: 4,\n TIMID: 5,\n LONELY: 6,\n DOCILE: 7,\n MILD: 8,\n GENTLE: 9,\n HASTY: 10,\n ADAMANT: 11,\n IMPISH: 12,\n BASHFUL: 13,\n CAREFUL: 14,\n RASH: 15,\n JOLLY: 16,\n NAUGHTY: 17,\n LAX: 18,\n QUIRKY: 19,\n NAIVE: 20,\n BRAVE: 21,\n RELAXED: 22,\n QUIET: 23,\n SASSY: 24,\n SERIOUS: 25,\n} as const;\n\nexport const POKEATHLON_STATS = {\n SPEED: 1,\n POWER: 2,\n SKILL: 3,\n STAMINA: 4,\n JUMP: 5,\n} as const;\n\nexport const POKEMON_COLORS = {\n BLACK: 1,\n BLUE: 2,\n BROWN: 3,\n GRAY: 4,\n GREEN: 5,\n PINK: 6,\n PURPLE: 7,\n RED: 8,\n WHITE: 9,\n YELLOW: 10,\n} as const;\n\nexport const POKEMON_HABITATS = {\n CAVE: 1,\n FOREST: 2,\n GRASSLAND: 3,\n MOUNTAIN: 4,\n RARE: 5,\n ROUGH_TERRAIN: 6,\n SEA: 7,\n URBAN: 8,\n WATERS_EDGE: 9,\n /**\n * @deprecated Misspelled: the endpoint names this `mountain`.\n * Use {@link POKEMON_HABITATS.MOUNTAIN}. Removed in 3.0.\n */\n MONTAIN: 4,\n} as const;\n\nexport const POKEMON_SHAPES = {\n BALL: 1,\n SQUIGGLE: 2,\n FISH: 3,\n ARMS: 4,\n BLOB: 5,\n UPRIGHT: 6,\n LEGS: 7,\n QUADRUPED: 8,\n WINGS: 9,\n TENTACLES: 10,\n HEADS: 11,\n HUMANOID: 12,\n BUG_WINGS: 13,\n ARMOR: 14,\n} as const;\n\nexport const STATS = {\n HP: 1,\n ATTACK: 2,\n DEFENSE: 3,\n SPECIAL_ATTACK: 4,\n SPECIAL_DEFENSE: 5,\n SPEED: 6,\n ACCURACY: 7,\n EVASION: 8,\n SPECIAL: 9,\n} as const;\n\nexport const TYPES = {\n NORMAL: 1,\n FIGHTING: 2,\n FLYING: 3,\n POISON: 4,\n GROUND: 5,\n ROCK: 6,\n BUG: 7,\n GHOST: 8,\n STEEL: 9,\n FIRE: 10,\n WATER: 11,\n GRASS: 12,\n ELECTRIC: 13,\n PSYCHIC: 14,\n ICE: 15,\n DRAGON: 16,\n DARK: 17,\n FAIRY: 18,\n STELLAR: 19,\n UNKNOWN: 10_001,\n SHADOW: 10_002,\n} as const;\n\n/**\n * ## Type Name\n * A battle type as the PokéAPI names it, which is what a\n * `NamedAPIResource<Type>` carries and what the type chart is keyed by.\n *\n * The eighteen types a Pokémon can be, and `stellar`, which is a Tera type and\n * nothing else. `unknown` and `shadow` are in {@link TYPES} but not here: they\n * are artefacts of Generation II's internals and of Colosseum/XD, they appear in\n * no damage relation, and a table keyed by them would be a table with two entries\n * nothing can ever fill.\n *\n * Written out rather than derived from {@link TYPES}, for the same reason\n * `GenerationName` is: the set is closed, and the two exclusions are a decision\n * rather than a transformation.\n */\nexport type TypeName =\n | \"normal\"\n | \"fighting\"\n | \"flying\"\n | \"poison\"\n | \"ground\"\n | \"rock\"\n | \"bug\"\n | \"ghost\"\n | \"steel\"\n | \"fire\"\n | \"water\"\n | \"grass\"\n | \"electric\"\n | \"psychic\"\n | \"ice\"\n | \"dragon\"\n | \"dark\"\n | \"fairy\"\n | \"stellar\";\n","export const BASE_URL = {\n REST: \"https://pokeapi.co/api/v2\",\n /** Root of the sprite repository the API's own sprite URLs point at. */\n SPRITES: \"https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites\",\n} as const;\n","export const LANGUAGES = {\n JA_HRKT: 1,\n JA_ROMA: 2,\n KO: 3,\n ZH_HANT: 4,\n FR: 5,\n DE: 6,\n ES: 7,\n IT: 8,\n EN: 9,\n CS: 10,\n JA: 11,\n ZH_HANS: 12,\n PT_BR: 13,\n ES_419: 14,\n} as const;\n","export * from \"./berries\";\nexport * from \"./contests\";\nexport * from \"./currencies\";\nexport * from \"./encounters\";\nexport * from \"./endpoints\";\nexport * from \"./evolutions\";\nexport * from \"./games\";\nexport * from \"./items\";\nexport * from \"./locations\";\nexport * from \"./moves\";\nexport * from \"./pokemon\";\nexport * from \"./urls\";\nexport * from \"./utilities\";\n","/** Five minutes. */\nconst DEFAULT_TTL = 300_000;\nconst DEFAULT_MAX_ENTRIES = 500;\n\n/**\n * ## Cache Store\n * The contract a client uses to cache responses, keyed by request URL.\n *\n * Every method may return a promise, so remote backends (Redis, KV stores) work\n * as-is. Values cross this boundary as parsed objects; expiry is the store's own\n * business.\n */\nexport interface CacheStore {\n get(key: string): unknown | Promise<unknown>;\n set(key: string, value: unknown): void | Promise<void>;\n delete?(key: string): void | Promise<void>;\n clear?(): void | Promise<void>;\n}\n\n/** Default namespace for the keys {@link WebStorageCache} owns. */\nconst DEFAULT_PREFIX = \"pokenode:\";\n\n/**\n * How many entries a bounded store keeps.\n *\n * A non-finite limit falls back to the default rather than being clamped:\n * `size >= NaN` is never true, and a bound that is never reached is not a bound\n * — `maxEntries` is exactly the sort of option that arrives as\n * `Number(process.env.CACHE_SIZE)`. Zero and below keep nothing.\n */\nconst entryLimit = (value: number | undefined, fallback: number): number =>\n value !== undefined && Number.isFinite(value) ? Math.max(Math.floor(value), 0) : fallback;\n\n/**\n * ## Memory Cache Options\n * Used to configure the default in-memory store.\n */\nexport interface MemoryCacheOptions {\n /** How long a cached response stays fresh, in milliseconds. Defaults to 5 minutes. */\n ttl?: number;\n /**\n * Maximum number of responses kept. The least recently used entry is evicted.\n * Defaults to 500; zero keeps none.\n */\n maxEntries?: number;\n}\n\ninterface CacheEntry {\n value: unknown;\n expiresAt: number;\n}\n\n/**\n * ## Memory Cache\n * The default {@link CacheStore}: a bounded, time-to-live cache held in memory.\n *\n * Values are stored and returned by reference — mutating a response also mutates\n * what later cache hits return, so treat responses as read-only.\n */\nexport class MemoryCache implements CacheStore {\n private readonly entries = new Map<string, CacheEntry>();\n private readonly ttl: number;\n private readonly maxEntries: number;\n\n constructor(options?: MemoryCacheOptions) {\n this.ttl = options?.ttl ?? DEFAULT_TTL;\n this.maxEntries = entryLimit(options?.maxEntries, DEFAULT_MAX_ENTRIES);\n }\n\n get(key: string): unknown {\n const entry = this.entries.get(key);\n\n if (!entry) {\n return undefined;\n }\n\n if (entry.expiresAt <= Date.now()) {\n this.entries.delete(key);\n return undefined;\n }\n\n // Re-insert so `entries` stays ordered least- to most-recently used.\n this.entries.delete(key);\n this.entries.set(key, entry);\n\n return entry.value;\n }\n\n set(key: string, value: unknown): void {\n // Delete first so an update moves the key to the most-recently-used end.\n this.entries.delete(key);\n\n // A store with no room keeps nothing, rather than the one entry an eviction\n // that has nothing to evict would leave behind.\n if (this.maxEntries === 0) {\n return;\n }\n\n if (this.entries.size >= this.maxEntries) {\n const oldest = this.entries.keys().next();\n if (!oldest.done) {\n this.entries.delete(oldest.value);\n }\n }\n\n this.entries.set(key, { value, expiresAt: Date.now() + this.ttl });\n }\n\n delete(key: string): void {\n this.entries.delete(key);\n }\n\n clear(): void {\n this.entries.clear();\n }\n}\n\n/** How many URLs an {@link EtagStore} remembers before evicting the oldest. */\nconst DEFAULT_ETAG_ENTRIES = 500;\n\n/**\n * ## Etag Entry\n * What a URL last answered with, and the validator that says so.\n */\nexport interface EtagEntry {\n /** The `ETag` the response carried. */\n etag: string;\n /** The parsed body that `etag` identifies. */\n value: unknown;\n}\n\n/**\n * ## Etag Store Options\n * Used to configure an {@link EtagStore}.\n */\nexport interface EtagStoreOptions {\n /**\n * How many URLs to remember. The least recently used is evicted. Defaults to\n * 500; zero remembers none.\n */\n maxEntries?: number;\n}\n\n/**\n * ## Etag Store\n * Remembers the `ETag` each URL answered with, and the body it identified, so an\n * expired cache entry can be revalidated instead of downloaded again.\n *\n * Deliberately not a {@link CacheStore}: the two answer different questions. A\n * `CacheStore` says \"this response is still fresh, use it\"; this says \"here is\n * what the response was last time, ask the server whether it still holds\". They\n * are kept apart so that a store someone else owns — a shared Redis — is never\n * given a second key shape, and `cache.get(url)` keeps returning the resource\n * itself.\n *\n * Entries live in memory and are never persisted: an `ETag` is only worth what\n * the body beside it is, and the body is what would cost memory to keep.\n */\nexport class EtagStore {\n private readonly entries = new Map<string, EtagEntry>();\n private readonly maxEntries: number;\n\n constructor(options?: EtagStoreOptions) {\n this.maxEntries = entryLimit(options?.maxEntries, DEFAULT_ETAG_ENTRIES);\n }\n\n get(url: string): EtagEntry | undefined {\n const entry = this.entries.get(url);\n\n if (!entry) {\n return undefined;\n }\n\n // Re-insert so `entries` stays ordered least- to most-recently used.\n this.entries.delete(url);\n this.entries.set(url, entry);\n\n return entry;\n }\n\n set(url: string, entry: EtagEntry): void {\n this.entries.delete(url);\n\n if (this.maxEntries === 0) {\n return;\n }\n\n if (this.entries.size >= this.maxEntries) {\n const oldest = this.entries.keys().next();\n\n if (!oldest.done) {\n this.entries.delete(oldest.value);\n }\n }\n\n this.entries.set(url, entry);\n }\n\n clear(): void {\n this.entries.clear();\n }\n}\n\n/**\n * ## Web Storage Like\n * The part of the browser's `Storage` interface a {@link WebStorageCache} uses.\n *\n * Declared structurally rather than as the DOM's `Storage`: the package compiles\n * without `lib.dom`, and stays usable anywhere the same shape exists.\n *\n * Every method may return a promise, so a React Native `AsyncStorage` works as-is.\n * Key enumeration is the one place the two shapes differ: `Storage` exposes\n * `length` and `key(index)`, `AsyncStorage` exposes `getAllKeys`, and a property\n * cannot be awaited — so both are accepted, and a storage offering neither still\n * caches; it just never evicts or clears.\n */\nexport interface WebStorageLike {\n getItem(key: string): string | null | Promise<string | null>;\n setItem(key: string, value: string): void | Promise<void>;\n removeItem(key: string): void | Promise<void>;\n /** Every key held, this store's and the application's alike. */\n getAllKeys?(): readonly string[] | Promise<readonly string[]>;\n key?(index: number): string | null;\n readonly length?: number;\n}\n\n/**\n * ## Web Storage Cache Options\n * Used to configure a store backed by `localStorage` or `sessionStorage`.\n */\nexport interface WebStorageCacheOptions {\n /**\n * Where entries are kept. Pass `localStorage`, `sessionStorage`, a React Native\n * `AsyncStorage`, or anything else matching {@link WebStorageLike}.\n */\n storage: WebStorageLike;\n /** How long a cached response stays fresh, in milliseconds. Defaults to 5 minutes. */\n ttl?: number;\n /** Namespace for the keys this store writes. Defaults to `pokenode:`. */\n prefix?: string;\n}\n\n/**\n * ## Web Storage Cache\n * A {@link CacheStore} backed by `localStorage` or `sessionStorage`, so a cached\n * response survives a page reload.\n *\n * ```ts\n * const api = new PokemonClient({ cache: new WebStorageCache({ storage: localStorage }) });\n * ```\n *\n * Only keys under {@link WebStorageCacheOptions.prefix} are ever read, evicted or\n * cleared — the storage is assumed to be shared with the surrounding application.\n *\n * Values round-trip through JSON, so unlike {@link MemoryCache} every hit returns a\n * fresh copy. Anything a `JSON.stringify` cannot represent does not survive, which\n * covers every PokéAPI response.\n *\n * A storage that throws instead of answering is treated as empty: a read is a miss\n * and a write is dropped, because neither is worth failing the request that\n * triggered it over.\n */\nexport class WebStorageCache implements CacheStore {\n private readonly storage: WebStorageLike;\n private readonly ttl: number;\n private readonly prefix: string;\n\n constructor(options: WebStorageCacheOptions) {\n this.storage = options.storage;\n this.ttl = options.ttl ?? DEFAULT_TTL;\n this.prefix = options.prefix ?? DEFAULT_PREFIX;\n }\n\n async get(key: string): Promise<unknown> {\n const entry = await this.read(this.prefix + key);\n\n if (!entry) {\n return undefined;\n }\n\n if (entry.expiresAt <= Date.now()) {\n await this.remove(this.prefix + key);\n return undefined;\n }\n\n return entry.value;\n }\n\n async set(key: string, value: unknown): Promise<void> {\n const entry = JSON.stringify({ value, expiresAt: Date.now() + this.ttl });\n\n try {\n await this.storage.setItem(this.prefix + key, entry);\n } catch {\n // Out of quota, most likely. Make room among this store's own keys and try\n // once more; a cache write that cannot land must not fail the request that\n // triggered it, so a second failure is dropped.\n await this.evict();\n\n try {\n await this.storage.setItem(this.prefix + key, entry);\n } catch {\n return;\n }\n }\n }\n\n async delete(key: string): Promise<void> {\n await this.storage.removeItem(this.prefix + key);\n }\n\n async clear(): Promise<void> {\n for (const key of await this.ownKeys()) {\n await this.remove(key);\n }\n }\n\n /** Reads a namespaced key, treating unreadable content as a miss. */\n private async read(key: string): Promise<CacheEntry | undefined> {\n let stored: string | null;\n\n try {\n stored = await this.storage.getItem(key);\n } catch {\n // A storage that refuses to be read — Safari with storage blocked, a shim\n // that throws — is a cache miss, not a failed request. The response the\n // caller asked for is still one fetch away.\n return undefined;\n }\n\n if (stored === null) {\n return undefined;\n }\n\n try {\n return JSON.parse(stored) as CacheEntry;\n } catch {\n // Written by an older version, or by something else under the same prefix.\n await this.remove(key);\n return undefined;\n }\n }\n\n /**\n * Frees space by dropping expired entries, falling back to the ones closest to\n * expiring when nothing has expired yet.\n */\n private async evict(): Promise<void> {\n const keys = await this.ownKeys();\n const entries = await Promise.all(\n keys.map(async (key) => ({ key, expiresAt: (await this.read(key))?.expiresAt })),\n );\n const now = Date.now();\n const expired = entries.filter(({ expiresAt }) => expiresAt === undefined || expiresAt <= now);\n\n if (expired.length > 0) {\n for (const { key } of expired) {\n await this.remove(key);\n }\n\n return;\n }\n\n const soonest = entries.sort((a, b) => (a.expiresAt ?? 0) - (b.expiresAt ?? 0));\n\n for (const { key } of soonest.slice(0, Math.ceil(soonest.length / 4))) {\n await this.remove(key);\n }\n }\n\n /**\n * Collects this store's keys before any removal: `key(index)` walks a list that\n * shifts underneath a loop that deletes as it goes.\n */\n private async ownKeys(): Promise<string[]> {\n return (await this.allKeys()).filter((key) => key.startsWith(this.prefix));\n }\n\n /**\n * Every key the storage holds, however it is willing to list them. A storage\n * offering no enumeration at all reports none, which leaves eviction and\n * `clear` as no-ops rather than an error on a path that only tidies up.\n */\n private async allKeys(): Promise<string[]> {\n try {\n if (this.storage.getAllKeys !== undefined) {\n return [...(await this.storage.getAllKeys())];\n }\n\n const { key, length } = this.storage;\n\n if (key === undefined || length === undefined) {\n return [];\n }\n\n const keys: string[] = [];\n\n for (let index = 0; index < length; index += 1) {\n const found = key.call(this.storage, index);\n\n if (found !== null) {\n keys.push(found);\n }\n }\n\n return keys;\n } catch {\n return [];\n }\n }\n\n /** Removes a key on a path that is only tidying up, where a refusal is moot. */\n private async remove(key: string): Promise<void> {\n try {\n await this.storage.removeItem(key);\n } catch {\n // The entry stays until the storage lets it go; a read of it is a miss\n // either way, since it is expired or unparseable.\n }\n }\n}\n","/**\n * Brands the error, so the guard can match on it instead of the prototype chain:\n * a tree loading both the ESM and the CJS build has two distinct classes.\n */\nconst ERROR_KIND = \"pokenode:http\";\n\n/**\n * ## Pokenode Error\n * Thrown when the PokéAPI answers with a non-2xx status. Transport failures are\n * not wrapped — the native error propagates untouched.\n */\nexport class PokenodeError extends Error {\n override readonly name = \"PokenodeError\";\n readonly kind = ERROR_KIND;\n\n /** HTTP status code of the response. */\n readonly status: number;\n /** HTTP status text of the response. */\n readonly statusText: string;\n /** URL that produced the error. */\n readonly url: string;\n /** Parsed response body, when the error response carried JSON. */\n readonly body: unknown;\n\n /**\n * @param message Overrides the default text, for a status whose failure is not\n * self-explanatory.\n */\n constructor(response: Response, body: unknown, message?: string) {\n super(message ?? `Request to ${response.url} failed with status ${response.status}`);\n\n this.status = response.status;\n this.statusText = response.statusText;\n this.url = response.url;\n this.body = body;\n }\n\n /** Whether the error came from a pokenode-ts client. */\n static isPokenodeError(error: unknown): error is PokenodeError {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"kind\" in error &&\n (error as { kind: unknown }).kind === ERROR_KIND\n );\n }\n}\n\n/**\n * Builds a {@link PokenodeError} from a failed response, reading the body when\n * it is JSON. The PokéAPI answers 404s with plain text, so a parse failure is\n * expected and leaves `body` undefined.\n */\nexport const toPokenodeError = async (\n response: Response,\n message?: string,\n): Promise<PokenodeError> => {\n let body: unknown;\n\n try {\n body = await response.json();\n } catch {\n body = undefined;\n }\n\n return new PokenodeError(response, body, message);\n};\n","/**\n * Fields shared by every payload.\n *\n * The text is carried twice on purpose. pino, bunyan and roarr read `msg`;\n * winston reads `message`. Sending both is what lets a logger from either family\n * be passed straight in, with no adapter to write and nothing logged as\n * `undefined`.\n */\ninterface LogFields {\n /** Which point of the request lifecycle this is, for filtering. */\n event: \"request\" | \"response\" | \"retry\" | \"cancelled\" | \"error\";\n msg: string;\n message: string;\n /** The request URL, with any credentials the base URL carried removed. */\n url: string;\n}\n\n/**\n * ## Log Request Payload\n * A request is about to be resolved, from cache or over the network.\n */\nexport interface LogRequestPayload extends LogFields {\n event: \"request\";\n /** The HTTP method, uppercase, as RFC 9110 and OpenTelemetry both expect. */\n method: string;\n}\n\n/**\n * ## Log Response Payload\n * A response was produced.\n */\nexport interface LogResponsePayload extends LogFields {\n event: \"response\";\n status: number;\n /**\n * Where the response came from.\n *\n * - `network` — a round trip was made.\n * - `cache` — served by the {@link CacheStore}; nothing left the process.\n * - `in-flight` — an identical request was already on the wire and this caller\n * shared it, so it made no round trip of its own.\n * - `revalidated` — a round trip was made, the API answered 304, and the body\n * already held for that URL was reused. Cheap, but not free.\n *\n * Counting `network` and `revalidated` gives the number of requests the\n * PokéAPI actually saw. Every caller reports, so counting all four gives the\n * number of calls the application made.\n */\n source: \"network\" | \"cache\" | \"in-flight\" | \"revalidated\";\n /** How long the client took to resolve the request, in milliseconds. */\n durationMs: number;\n}\n\n/**\n * ## Log Retry Payload\n * An attempt failed and another one is coming.\n *\n * Only emitted when `retry` is configured, and never for the attempt that gives\n * up — that one is a `response` or an `error` like any other. Counting these\n * gives the round trips the PokéAPI saw beyond the ones it answered.\n */\nexport interface LogRetryPayload extends LogFields {\n event: \"retry\";\n /** Which attempt just failed, counting from one. */\n attempt: number;\n /** How long the client will wait before the next one, in milliseconds. */\n delayMs: number;\n /** The status that failed. Absent when the attempt never got a response. */\n status?: number;\n}\n\n/**\n * ## Log Cancelled Payload\n * A request was cancelled by the scope it was made through.\n *\n * A caller that hangs up asked for this, so it is not a failure and does not\n * reach `error`: a handler that scopes every request would otherwise report its\n * own timeouts as its error rate. Counting `response` and `cancelled` together\n * accounts for every `request` logged.\n */\nexport interface LogCancelledPayload extends LogFields {\n event: \"cancelled\";\n /** `signal.reason`, or the `TimeoutError` a scoped timeout raised. */\n reason: unknown;\n /** How long the request had been running when it was cancelled, in milliseconds. */\n durationMs: number;\n}\n\n/**\n * ## Log Error Payload\n * A request failed.\n *\n * The error is carried twice for the same reason the message is: pino runs its\n * error serializer on `err` and nothing else, so an `Error` under any other key\n * would reach the log as `{}` — no message, no stack.\n */\nexport interface LogErrorPayload extends LogFields {\n event: \"error\";\n /** Whatever `fetch` or the API produced. */\n err: unknown;\n error: unknown;\n}\n\n/**\n * ## Logger\n * Where a client reports what it did.\n *\n * Deliberately the shape every logging library already has, so one can be passed\n * without glue:\n *\n * ```ts\n * new PokemonClient({ logger: pino() });\n * new PokemonClient({ logger: console });\n * new PokemonClient({ logger: winston.createLogger() });\n * ```\n *\n * Requests, responses and cancellations go to `debug`; failures go to `error`.\n * Nothing is logged unless a logger is passed, and a client never picks a level\n * of its own.\n */\nexport interface Logger {\n debug(\n payload: LogRequestPayload | LogResponsePayload | LogRetryPayload | LogCancelledPayload,\n ): void;\n error(payload: LogErrorPayload): void;\n}\n\n/**\n * Builds the message keys both logging families expect. Internal — the payload\n * types are the public contract.\n */\nexport const logMessage = (text: string): { msg: string; message: string } => ({\n msg: text,\n message: text,\n});\n\n/**\n * A {@link Logger} that writes the request lifecycle to the console as one\n * formatted line per event.\n *\n * `console` itself is a valid {@link Logger} and logs the payload as an object;\n * this is for when the terminal should stay readable.\n */\nexport const consoleLogger: Logger = {\n debug(payload) {\n if (payload.event === \"request\") {\n console.log(`[ Request Config ] ${payload.method} | ${payload.url}`);\n return;\n }\n\n if (payload.event === \"retry\") {\n console.log(\n `[ Retry ] ATTEMPT ${payload.attempt} | STATUS ${payload.status ?? \"NONE\"} | IN ${payload.delayMs.toFixed(0)}ms | ${payload.url}`,\n );\n return;\n }\n\n if (payload.event === \"cancelled\") {\n console.log(`[ Cancelled ] ${payload.url} | AFTER ${payload.durationMs.toFixed(1)}ms`);\n return;\n }\n\n console.log(\n `[ Response ] STATUS ${payload.status} | ${payload.source.toUpperCase()} | ${payload.durationMs.toFixed(1)}ms`,\n );\n },\n\n error({ url, err }) {\n const { name, message } =\n err instanceof Error ? err : { name: \"UNKNOWN\", message: String(err) };\n\n console.error(`[ Response Error ] ${url} | CODE ${name} | ${message}`);\n },\n};\n","/**\n * A request already on the wire, and what it takes to cancel it.\n *\n * `waiters` counts the callers still interested. The request is aborted only\n * when the last of them has left, so one caller giving up does not cancel the\n * round trip the others are sharing.\n */\ninterface Request<T> {\n promise: Promise<T>;\n /** Absent when the caller that started the request had nothing to cancel it with. */\n controller: AbortController | undefined;\n waiters: number;\n}\n\n/** A resolved request, and whether this caller paid for it. */\nexport interface Shared<T> {\n value: T;\n /** Whether an identical request was already on the wire and this caller joined it. */\n joined: boolean;\n}\n\n/**\n * ## In Flight\n * The requests currently on the wire, keyed by URL, so concurrent callers asking\n * for the same one share a single round trip.\n *\n * Held by a transport's shared state and passed by reference, so a scoped\n * transport joins the requests already running rather than starting its own.\n *\n * Internal, and deliberately ignorant of what a request resolves to: it owns the\n * bookkeeping — who is still waiting, who may cancel, when an entry is forgotten\n * — and nothing about HTTP.\n */\nexport class InFlight<T> {\n private readonly requests = new Map<string, Request<T>>();\n\n /**\n * Resolves `key` through the request already running for it, or through a new\n * one started by `start`.\n *\n * `start` is handed the signal to cancel with, which is not the caller's: the\n * callers sharing a request come and go, and only the last one to leave may\n * cancel it.\n */\n async share(\n key: string,\n signal: AbortSignal | undefined,\n start: (signal: AbortSignal | undefined) => Promise<T>,\n ): Promise<Shared<T>> {\n const pending = this.requests.get(key);\n const entry = pending ?? this.dispatch(key, signal, start);\n\n return { value: await this.join(key, entry, signal), joined: pending !== undefined };\n }\n\n /** Issues a request and remembers it, so a concurrent caller can share it. */\n private dispatch(\n key: string,\n signal: AbortSignal | undefined,\n start: (signal: AbortSignal | undefined) => Promise<T>,\n ): Request<T> {\n const controller = signal ? new AbortController() : undefined;\n const entry: Request<T> = {\n promise: start(controller?.signal),\n controller,\n waiters: 0,\n };\n\n entry.promise = entry.promise.finally(() => this.release(key, entry));\n\n // A request abandoned by every caller rejects with nobody left awaiting it.\n // This handler exists only so that rejection is not unhandled; each caller\n // still sees the failure through its own `join`.\n entry.promise.catch(() => {});\n\n this.requests.set(key, entry);\n\n return entry;\n }\n\n /**\n * Forgets a request, unless a later caller has already replaced it: a request\n * that was aborted leaves the map before it settles, and the one dispatched in\n * its place must survive its predecessor finishing.\n */\n private release(key: string, entry: Request<T>): void {\n if (this.requests.get(key) === entry) {\n this.requests.delete(key);\n }\n }\n\n /**\n * Awaits a request, cancelling it if this caller was the last one interested.\n *\n * A caller with no signal never leaves early, so it holds the request open for\n * everyone — including a scoped caller that joined later and gave up.\n */\n private join(key: string, entry: Request<T>, signal: AbortSignal | undefined): Promise<T> {\n entry.waiters += 1;\n\n if (!signal) {\n return entry.promise;\n }\n\n return new Promise<T>((resolve, reject) => {\n const leave = (): void => {\n entry.waiters -= 1;\n\n if (entry.waiters > 0) {\n return;\n }\n\n // Dropped from the map before the abort settles it: a caller arriving in\n // between would otherwise join a request already on its way out and\n // inherit an abort it never asked for.\n this.release(key, entry);\n entry.controller?.abort(signal.reason);\n };\n\n if (signal.aborted) {\n leave();\n reject(signal.reason);\n return;\n }\n\n const onAbort = (): void => {\n leave();\n reject(signal.reason);\n };\n\n signal.addEventListener(\"abort\", onAbort, { once: true });\n\n entry.promise.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error);\n },\n );\n });\n }\n}\n","/**\n * How many requests the helpers that fetch many resources at once will run in\n * parallel. Kept low on purpose: see the PokéAPI fair-use policy.\n */\nexport const DEFAULT_CONCURRENCY = 4;\n\n/**\n * Runs `task` over `items` with at most `concurrency` of them in flight, and\n * returns the results in the order the items came in.\n *\n * Internal: the PokéAPI's fair-use policy asks clients not to flood it, so the\n * places that resolve many links at once go through here rather than\n * `Promise.all`.\n *\n * The first failure stops the pool — workers check before taking more work, so\n * a rejection does not leave a tail of requests running for a result nobody will\n * read.\n */\nexport const mapWithConcurrency = async <I, O>(\n items: readonly I[],\n concurrency: number,\n task: (item: I) => Promise<O>,\n): Promise<O[]> => {\n const results = new Array<O>(items.length);\n let cursor = 0;\n let failed = false;\n\n const worker = async (): Promise<void> => {\n while (cursor < items.length && !failed) {\n const index = cursor;\n cursor += 1;\n\n try {\n results[index] = await task(items[index] as I);\n } catch (error) {\n failed = true;\n throw error;\n }\n }\n };\n\n // A non-finite count falls back to the default rather than being clamped:\n // `Math.max(NaN, 1)` is `NaN`, `Array.from({ length: NaN })` is empty, and a\n // pool with no workers returns a hole per item instead of failing. This is\n // exactly the sort of option that arrives as `Number(process.env.CONCURRENCY)`.\n const requested = Number.isFinite(concurrency) ? concurrency : DEFAULT_CONCURRENCY;\n const workers = Array.from({ length: Math.min(Math.max(requested, 1), items.length) }, () =>\n worker(),\n );\n\n await Promise.all(workers);\n\n return results;\n};\n","import type { ListFn, PaginateOptions } from \"../clients/base\";\nimport type { APIResource } from \"../models/common/resource\";\nimport { DEFAULT_CONCURRENCY, mapWithConcurrency } from \"./pool\";\n\n/**\n * The PokéAPI's own default, and `Transport.list`'s, so a walk pages the way a\n * hand-written loop would.\n */\nexport const DEFAULT_PAGE_SIZE = 20;\n\n/**\n * Walks every page of a list, yielding one entry at a time.\n *\n * `resolve` is passed in rather than a transport: this module would otherwise\n * have to import the one that imports it.\n */\nexport async function* walk<T>(\n list: ListFn<APIResource<T>>,\n resolve: (link: APIResource<T>) => Promise<T>,\n options?: PaginateOptions,\n): AsyncGenerator<APIResource<T> | T> {\n const pageSize = options?.pageSize ?? DEFAULT_PAGE_SIZE;\n const concurrency = options?.concurrency ?? DEFAULT_CONCURRENCY;\n let offset = 0;\n\n while (true) {\n const page = await list(offset, pageSize);\n\n if (page.results.length === 0) {\n return;\n }\n\n if (options?.resolve) {\n // Resolved a page at a time: the order callers see stays the order the\n // API listed, however the requests within a page happen to finish.\n const resources = await mapWithConcurrency(page.results, concurrency, resolve);\n\n yield* resources;\n } else {\n yield* page.results;\n }\n\n offset += page.results.length;\n\n // A short page ends the walk on its own: `count` is upstream's word for how\n // much there is, and the results are the client's own evidence.\n if (page.results.length < pageSize || offset >= page.count) {\n return;\n }\n }\n}\n","import type { RetryOptions } from \"../clients/base\";\nimport { toPokenodeError } from \"../config/errors\";\nimport { type Logger, logMessage } from \"../config/logger\";\n\nconst DEFAULT_RETRY_ATTEMPTS = 3;\nconst DEFAULT_INITIAL_DELAY = 300;\nconst DEFAULT_MAX_DELAY = 5_000;\n/** Transient by definition: rate limiting, and the gateway failures around it. */\nconst DEFAULT_RETRY_STATUSES = [429, 500, 502, 503, 504];\n\n/**\n * How many attempts a request gets, the first one included. A fractional count\n * is rounded down, so `2.5` is two attempts rather than the three that\n * `attempt >= attempts` would otherwise allow.\n *\n * A non-finite count falls back to the default rather than being clamped:\n * `Math.max(NaN, 1)` is `NaN`, and an attempt loop bounded by `NaN` never ends.\n * `attempts` is exactly the sort of option that arrives as\n * `Number(process.env.RETRIES)`.\n */\nexport const attemptCount = (retry: RetryOptions | undefined): number => {\n if (!retry) {\n return 1;\n }\n\n const requested = retry.attempts ?? DEFAULT_RETRY_ATTEMPTS;\n\n return Number.isFinite(requested) ? Math.max(Math.floor(requested), 1) : DEFAULT_RETRY_ATTEMPTS;\n};\n\n/**\n * A configured wait, in milliseconds, or the default when it is not a number\n * this client can wait for.\n *\n * A non-finite value falls back for the reason given on {@link attemptCount}:\n * `setTimeout` reads a `NaN` delay as zero, and `x > NaN` is false, so an\n * unusable option spends every attempt at once — or accepts any `Retry-After`\n * it is sent.\n */\nconst delayOption = (value: number | undefined, fallback: number): number =>\n value !== undefined && Number.isFinite(value) ? Math.max(value, 0) : fallback;\n\n/**\n * Reads `Retry-After`, which RFC 9110 allows to be either a number of seconds or\n * an HTTP date. Returns milliseconds, or nothing when the header is absent or\n * unparseable.\n */\nconst toRetryAfterMs = (header: string | null): number | undefined => {\n if (header === null) {\n return undefined;\n }\n\n // `Number(\"\")` is a finite 0, which would read a blank header as permission to\n // retry immediately — the opposite of what the header is ever sent to say.\n const value = header.trim();\n\n if (value === \"\") {\n return undefined;\n }\n\n const seconds = Number(value);\n\n if (Number.isFinite(seconds)) {\n return Math.max(seconds, 0) * 1_000;\n }\n\n const date = Date.parse(value);\n\n return Number.isNaN(date) ? undefined : Math.max(date - Date.now(), 0);\n};\n\n/**\n * Whether an error is a request being cancelled rather than failing. A cancelled\n * request is never retried: someone asked for it to stop.\n */\nexport const isAbort = (error: unknown, signal: AbortSignal | undefined): boolean =>\n signal?.aborted === true ||\n (error instanceof Error && (error.name === \"AbortError\" || error.name === \"TimeoutError\"));\n\n/** Waits, unless the request is cancelled first. */\nconst sleep = (ms: number, signal: AbortSignal | undefined): Promise<void> =>\n new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason);\n return;\n }\n\n const timer = setTimeout(() => {\n signal?.removeEventListener(\"abort\", onAbort);\n resolve();\n }, ms);\n\n // Node holds the event loop open for a pending timer, so a wait between\n // attempts would keep a process that has nothing else to do alive for it.\n // Optional because a browser's `setTimeout` returns a number.\n timer.unref?.();\n\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(signal?.reason);\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n\n/**\n * How long `Retry-After` asks this client to wait, or nothing when the wait is\n * {@link backoff}'s to calculate.\n *\n * @throws {PokenodeError} If the failure is not one this client attempts again.\n */\nexport const retryDelay = async (\n response: Response,\n isLast: boolean,\n retry: RetryOptions | undefined,\n): Promise<number | undefined> => {\n const statuses = retry?.statuses ?? DEFAULT_RETRY_STATUSES;\n const maxDelay = delayOption(retry?.maxDelay, DEFAULT_MAX_DELAY);\n\n if (isLast || !statuses.includes(response.status)) {\n throw await toPokenodeError(response);\n }\n\n const retryAfter = toRetryAfterMs(response.headers.get(\"Retry-After\"));\n\n // Asked to wait longer than this client is willing to: waiting less is\n // exactly what the header exists to prevent, so the attempt is the last.\n if (retryAfter !== undefined && retryAfter > maxDelay) {\n throw await toPokenodeError(response);\n }\n\n return retryAfter;\n};\n\n/** What one wait between attempts needs to know. */\nexport interface BackoffOptions {\n url: string;\n attempt: number;\n /** Absent when the attempt failed before there was a response to read. */\n status: number | undefined;\n /** What `Retry-After` asked for, when it asked for anything. */\n retryAfter: number | undefined;\n signal: AbortSignal | undefined;\n retry: RetryOptions | undefined;\n logger: Logger | undefined;\n}\n\n/**\n * Waits before the next attempt, and says so through the logger.\n *\n * The wait is half of a doubling window plus jitter over the other half, so\n * clients that failed together do not come back together, and none of them\n * comes back immediately. `Retry-After` replaces the calculation outright.\n */\nexport const backoff = async (options: BackoffOptions): Promise<void> => {\n const { url, attempt, status, retryAfter, signal, retry, logger } = options;\n const initialDelay = delayOption(retry?.initialDelay, DEFAULT_INITIAL_DELAY);\n const maxDelay = delayOption(retry?.maxDelay, DEFAULT_MAX_DELAY);\n const window = Math.min(initialDelay * 2 ** (attempt - 1), maxDelay);\n const delayMs = retryAfter ?? window / 2 + Math.random() * (window / 2);\n\n logger?.debug({\n event: \"retry\",\n ...logMessage(\"pokeapi request failed, retrying\"),\n url,\n attempt,\n delayMs,\n ...(status === undefined ? {} : { status }),\n });\n\n await sleep(delayMs, signal);\n};\n","import type { Endpoint } from \"../constants\";\n\n/**\n * Scanned rather than matched with `/\\/+$/`: that pattern backtracks through\n * every slash of a long run that turns out not to end the string, which is\n * quadratic on a URL an untrusted caller supplies. This walks each character\n * once.\n */\nexport const trimTrailingSlash = (url: string): string => {\n let end = url.length;\n\n while (end > 0 && url[end - 1] === \"/\") {\n end -= 1;\n }\n\n return url.slice(0, end);\n};\n\n/** Builds the paginated request path shared by both list methods. */\nexport const listPath = (endpoint: Endpoint, offset: number, limit: number): string => {\n const query = new URLSearchParams({ offset: String(offset), limit: String(limit) });\n\n return `${endpoint}?${query}`;\n};\n\n/**\n * Drops the trailing slash from a request URL, leaving any query string alone.\n *\n * Both call paths must produce one cache key: `Transport.resource` builds\n * `/berry/1`, while the PokéAPI's own links end in a slash.\n *\n * Split at the query rather than matched with a lookahead, for the reason given\n * on {@link trimTrailingSlash}.\n */\nexport const normalizeURL = (url: string): string => {\n const queryAt = url.indexOf(\"?\");\n\n if (queryAt === -1) {\n return trimTrailingSlash(url);\n }\n\n return trimTrailingSlash(url.slice(0, queryAt)) + url.slice(queryAt);\n};\n\n/** A path segment naming an API version, as in `/api/v2/berry/1`. */\nconst API_VERSION_SEGMENT = /^v\\d+$/;\n\n/**\n * Percent-decodes one userinfo component, leaving a component that cannot be\n * decoded as it stands: `URL` accepts sequences `decodeURIComponent` rejects —\n * `us%zzer` parses and then throws — and a credential nobody can decode is still\n * worth sending as written rather than failing the request over.\n */\nconst decodeUserinfo = (component: string): string => {\n try {\n return decodeURIComponent(component);\n } catch {\n return component;\n }\n};\n\n/** Base64-encodes userinfo as RFC 7617 wants it: UTF-8 bytes, percent-decoded. */\nconst toBasicAuth = (username: string, password: string): string => {\n const userinfo = `${decodeUserinfo(username)}:${decodeUserinfo(password)}`;\n const bytes = new TextEncoder().encode(userinfo);\n let latin1 = \"\";\n\n for (const byte of bytes) {\n latin1 += String.fromCodePoint(byte);\n }\n\n return `Basic ${btoa(latin1)}`;\n};\n\n/** A request URL and the `Authorization` header its userinfo became, if any. */\nexport interface CredentiallessURL {\n url: string;\n authorization: string | undefined;\n}\n\n/**\n * Moves any credentials a URL carries into an `Authorization` header.\n *\n * A self-hosted instance behind basic auth is configured as\n * `https://user:secret@host/api/v2`, and that password must not reach the wire\n * as userinfo: `fetch` rejects a credentialed URL outright, and everything\n * downstream of the URL — the log payload, the cache key — would carry it.\n *\n * A URL too malformed to parse cannot carry credentials in the first place, and\n * `fetch` is about to reject it anyway, so it is passed through untouched.\n *\n * The URL that comes back is what everything downstream keys on — the cache\n * entry, the in-flight map, the log line — so two calls to the same host under\n * different credentials share a cache entry and a round trip. That is the trade\n * this exists for: one instance behind one set of credentials. A client per\n * identity needs a `CacheStore` per identity to go with it.\n */\nexport const splitCredentials = (url: string): CredentiallessURL => {\n if (!url.includes(\"@\")) {\n return { url, authorization: undefined };\n }\n\n let parsed: URL;\n\n try {\n parsed = new URL(url);\n } catch {\n return { url, authorization: undefined };\n }\n\n if (!parsed.username && !parsed.password) {\n return { url, authorization: undefined };\n }\n\n const authorization = toBasicAuth(parsed.username, parsed.password);\n\n parsed.username = \"\";\n parsed.password = \"\";\n\n return { url: parsed.toString(), authorization };\n};\n\n/**\n * Reduces an absolute resource URL to the endpoint path to request.\n *\n * When the URL belongs to `baseURL`, the path is simply what follows it.\n * Otherwise — a link from pokeapi.co handed to a client aimed at a self-hosted\n * instance — the path after the API version segment is used, so the resource is\n * re-resolved against the client's own base rather than fetched from elsewhere.\n *\n * The version segment is matched on parsed URL components: a raw-string search\n * also matches a host like `api.v2.example.com`.\n */\nexport const toEndpointPath = (resourceURL: string, baseURL: string): string => {\n const resource = new URL(resourceURL);\n const base = new URL(baseURL);\n const basePath = trimTrailingSlash(base.pathname);\n\n if (\n resource.origin === base.origin &&\n (resource.pathname === basePath || resource.pathname.startsWith(`${basePath}/`))\n ) {\n return `${resource.pathname.slice(basePath.length)}${resource.search}`;\n }\n\n const segments = resource.pathname.split(\"/\");\n const version = segments.findIndex((segment) => API_VERSION_SEGMENT.test(segment));\n\n if (version === -1) {\n throw new TypeError(`Cannot resolve \"${resourceURL}\" against the base URL \"${baseURL}\"`);\n }\n\n return `/${segments.slice(version + 1).join(\"/\")}${resource.search}`;\n};\n","import type {\n ClientOptions,\n ClientStats,\n FetchLike,\n ListFn,\n PaginateOptions,\n RequestScope,\n ResourceLink,\n RetryOptions,\n} from \"../clients/base\";\nimport { type CacheStore, type EtagEntry, EtagStore, MemoryCache } from \"../config/cache\";\nimport { toPokenodeError } from \"../config/errors\";\nimport { type Logger, type LogResponsePayload, logMessage } from \"../config/logger\";\nimport { BASE_URL, type Endpoint } from \"../constants\";\nimport type { APIResource } from \"../models/common/resource\";\nimport { InFlight } from \"./inflight\";\nimport { DEFAULT_PAGE_SIZE, walk as walkPages } from \"./paginate\";\nimport { DEFAULT_CONCURRENCY, mapWithConcurrency } from \"./pool\";\nimport { attemptCount, backoff, isAbort, retryDelay } from \"./retry\";\nimport { listPath, normalizeURL, splitCredentials, toEndpointPath, trimTrailingSlash } from \"./url\";\n\n/** A parsed response body and the status it arrived with. */\ninterface FetchedResource {\n data: unknown;\n status: number;\n /** Whether the body came from an {@link EtagStore} rather than off the wire. */\n revalidated?: boolean;\n}\n\n/** Where a resolution came from, as the response log reports it. */\nconst responseSource = (\n joined: boolean,\n revalidated: boolean | undefined,\n): LogResponsePayload[\"source\"] => {\n if (joined) {\n return \"in-flight\";\n }\n\n return revalidated === true ? \"revalidated\" : \"network\";\n};\n\n/** Resolves the `revalidate` option to the store the client will keep, if any. */\nconst toEtagStore = (revalidate: boolean | EtagStore | undefined): EtagStore | undefined => {\n if (!revalidate) {\n return undefined;\n }\n\n return revalidate === true ? new EtagStore() : revalidate;\n};\n\n/** What a {@link Transport} was configured with, and never changes thereafter. */\ninterface TransportConfig {\n baseURL: string;\n fetch: FetchLike;\n logger: Logger | undefined;\n retry: RetryOptions | undefined;\n}\n\n/**\n * What a {@link Transport} shares with every transport derived from it.\n *\n * Held in one object and passed by reference, so a scoped transport joins the\n * cache, the validators and the requests already on the wire rather than\n * starting its own.\n */\ninterface TransportState {\n cache: CacheStore | undefined;\n etags: EtagStore | undefined;\n /** Requests already on the wire, so concurrent callers share one round trip. */\n inFlight: InFlight<FetchedResource>;\n /** One count per resolution, by where it came from. Shared for the same reason. */\n counts: Record<LogResponsePayload[\"source\"], number>;\n /**\n * Requests that left the process, counted where they are made rather than\n * where they resolve: a resolution retried twice is one `network` and three of\n * these, and only this number is what the API saw.\n */\n roundTrips: { count: number };\n}\n\n/**\n * ## Transport\n * Everything a client does that is not naming an endpoint: requests, caching,\n * retries, revalidation and logging. The rules it works to live beside it, one\n * concern per module — `./url`, `./retry`, `./paginate`, and `./inflight` for\n * the coalescing of concurrent requests.\n *\n * Internal. One transport is built per `MainClient` and handed to all twelve of\n * its section clients, which is what makes a resource fetched through one of\n * them cached — and coalesced — for the rest.\n */\nexport class Transport {\n constructor(\n private readonly config: TransportConfig,\n private readonly state: TransportState,\n private readonly scope: RequestScope = {},\n ) {}\n\n /** Builds a transport, and the state it will share, from public options. */\n static create(clientOptions?: ClientOptions): Transport {\n return new Transport(\n {\n baseURL: trimTrailingSlash(clientOptions?.baseURL ?? BASE_URL.REST),\n fetch: clientOptions?.fetch ?? ((input, init) => globalThis.fetch(input, init)),\n logger: clientOptions?.logger,\n retry: clientOptions?.retry,\n },\n {\n cache:\n clientOptions?.cache === false ? undefined : (clientOptions?.cache ?? new MemoryCache()),\n etags: toEtagStore(clientOptions?.revalidate),\n inFlight: new InFlight(),\n counts: { network: 0, cache: 0, \"in-flight\": 0, revalidated: 0 },\n roundTrips: { count: 0 },\n },\n );\n }\n\n /** The counts so far, as a snapshot: the state behind them keeps moving. */\n get stats(): ClientStats {\n const { network, cache, revalidated } = this.state.counts;\n\n return {\n network,\n cache,\n inFlight: this.state.counts[\"in-flight\"],\n revalidated,\n roundTrips: this.state.roundTrips.count,\n };\n }\n\n /** The store backing this transport, or `undefined` when caching is disabled. */\n get cache(): CacheStore | undefined {\n return this.state.cache;\n }\n\n /**\n * Derives a transport whose requests carry a signal, a timeout, or both.\n *\n * The derived transport shares this one's state, so a scoped call still joins\n * an identical unscoped one instead of repeating it.\n */\n with(scope: RequestScope): Transport {\n return new Transport(this.config, this.state, { ...this.scope, ...scope });\n }\n\n /**\n * Drops every cached response, and the validators held for them: an\n * {@link EtagStore} keeps the bodies it learned, so leaving it would answer\n * the next request with the very body that was just dropped.\n *\n * A {@link CacheStore} that does not implement `clear` is left alone.\n */\n async clear(): Promise<void> {\n await this.state.cache?.clear?.();\n this.state.etags?.clear();\n }\n\n /**\n * Retrieves a single resource by its endpoint and identifier.\n *\n * Every segment is percent-encoded. A name reaches here as whatever the caller\n * passed — `getBerryByName(req.query.name)` is the shape that call takes — and\n * unencoded a `?` in it becomes a query, a `/` another endpoint, and a `#` a\n * fragment that is dropped before the wire but not before the cache key. A\n * path below the endpoint is given as separate segments for that reason.\n */\n async resource<T>(endpoint: Endpoint, ...segments: (string | number)[]): Promise<T> {\n const path = segments.map((segment) => encodeURIComponent(segment)).join(\"/\");\n\n return this.request<T>(path === \"\" ? endpoint : `${endpoint}/${path}`);\n }\n\n /** Retrieves a resource by its URL, or by a link taken from another response. */\n async byURL<T>(resource: ResourceLink<T>, baseURL = this.config.baseURL): Promise<T> {\n const url = typeof resource === \"string\" ? resource : resource.url;\n\n return this.request<T>(toEndpointPath(url, baseURL), baseURL);\n }\n\n /** Retrieves one page of a list endpoint. */\n async list<T>(endpoint: Endpoint, offset = 0, limit = DEFAULT_PAGE_SIZE): Promise<T> {\n return this.request<T>(listPath(endpoint, offset, limit));\n }\n\n /** Fetches what several links point at, in the order they were given. */\n async resolveAll<T>(\n resources: readonly ResourceLink<T>[],\n concurrency = DEFAULT_CONCURRENCY,\n ): Promise<T[]> {\n return mapWithConcurrency(resources, concurrency, (resource) => this.byURL<T>(resource));\n }\n\n /** Walks every page of a list endpoint, yielding one entry at a time. */\n walk<T>(\n list: ListFn<APIResource<T>>,\n options?: PaginateOptions,\n ): AsyncGenerator<APIResource<T> | T> {\n return walkPages(list, (link) => this.byURL(link), options);\n }\n\n /**\n * Resolves a resource through the cache, then through any identical request\n * already in flight, and only then over the network.\n *\n * The URL is joined by concatenation: `new URL(path, base)` would discard the\n * base's own `/api/v2` path.\n */\n private async request<T>(path: string, baseURL = this.config.baseURL): Promise<T> {\n const rooted = path.startsWith(\"/\") ? path : `/${path}`;\n\n // Credentials leave the URL before anything else sees it: `fetch` rejects a\n // credentialed URL, and the cache key and log payload are built from this.\n const { url, authorization } = splitCredentials(\n normalizeURL(`${trimTrailingSlash(baseURL)}${rooted}`),\n );\n\n const startedAt = performance.now();\n\n this.config.logger?.debug({\n event: \"request\",\n ...logMessage(\"pokeapi request\"),\n method: \"GET\",\n url,\n });\n\n const signal = this.requestSignal();\n\n try {\n // Checked before anything else happens, and before the cache is consulted:\n // a call made through a scope that has already aborted must not reach the\n // network, and must not depend on what happens to be cached either.\n if (signal?.aborted) {\n throw signal.reason;\n }\n\n const cached = await this.state.cache?.get(url);\n\n if (cached !== undefined) {\n // A hit is timed like any other resolution: the number is small, but a\n // store on the far side of a network is not guaranteed to make it so.\n this.recordResponse(url, 200, \"cache\", startedAt);\n return cached as T;\n }\n\n // Every caller reports its own outcome, including one that only joined a\n // request someone else started: a `request` event with no `response` to\n // close it would make concurrent traffic unreadable. `source` is what keeps\n // the count of round trips honest when several callers share one.\n const { value, joined } = await this.state.inFlight.share(url, signal, (requestSignal) =>\n this.fetchResource(url, authorization, requestSignal),\n );\n\n this.recordResponse(url, value.status, responseSource(joined, value.revalidated), startedAt);\n\n return value.data as T;\n } catch (error) {\n // A cancelled request is not a failed one, by the same rule that stops the\n // retry loop from attempting it again.\n if (isAbort(error, signal)) {\n this.config.logger?.debug({\n event: \"cancelled\",\n ...logMessage(\"pokeapi request cancelled\"),\n url,\n reason: error,\n durationMs: performance.now() - startedAt,\n });\n throw error;\n }\n\n this.config.logger?.error({\n event: \"error\",\n ...logMessage(\"pokeapi request failed\"),\n url,\n err: error,\n error,\n });\n throw error;\n }\n }\n\n /**\n * The signal this scope puts on a request, or none when it has nothing to\n * cancel with. A timeout is created per request, not per scope: a scope is\n * derived once and used many times.\n */\n private requestSignal(): AbortSignal | undefined {\n const { signal, timeout } = this.scope;\n\n if (timeout === undefined) {\n return signal;\n }\n\n const expiry = AbortSignal.timeout(timeout);\n\n return signal ? AbortSignal.any([signal, expiry]) : expiry;\n }\n\n private async fetchResource(\n url: string,\n authorization: string | undefined,\n signal: AbortSignal | undefined,\n ): Promise<FetchedResource> {\n // Read once, before any attempt: an entry evicted while the request is in\n // flight must not turn a 304 into a response with no body to go with it.\n const known = this.state.etags?.get(url);\n const headers = {\n Accept: \"application/json\",\n ...(authorization === undefined ? {} : { Authorization: authorization }),\n ...(known === undefined ? {} : { \"If-None-Match\": known.etag }),\n };\n const init = signal ? { headers, signal } : { headers };\n const { retry, logger } = this.config;\n const attempts = attemptCount(retry);\n\n for (let attempt = 1; ; attempt += 1) {\n const isLast = attempt >= attempts;\n let response: Response;\n\n try {\n // Counted before the call rather than after: an attempt that throws\n // still left the process, and a retry loop nobody can see is what makes\n // a client cost more than its caller thinks.\n this.state.roundTrips.count += 1;\n response = await this.config.fetch(url, init);\n } catch (error) {\n // A cancelled request is not a failed one, so no attempt follows it.\n if (isLast || isAbort(error, signal)) {\n throw error;\n }\n\n await backoff({\n url,\n attempt,\n status: undefined,\n retryAfter: undefined,\n signal,\n retry,\n logger,\n });\n continue;\n }\n\n const resolved = await this.resolveResponse(url, response, known);\n\n if (resolved !== undefined) {\n return resolved;\n }\n\n const retryAfter = await retryDelay(response, isLast, retry);\n\n // The body is going nowhere, and an undrained one holds its connection.\n // Not awaited: an intercepted response may never settle the cancellation,\n // and nothing here depends on it having finished.\n response.body?.cancel().catch(() => {});\n await backoff({ url, attempt, status: response.status, retryAfter, signal, retry, logger });\n }\n }\n\n /**\n * The resource a response carries, or nothing when it carries none and another\n * attempt is the question.\n */\n private async resolveResponse(\n url: string,\n response: Response,\n known: EtagEntry | undefined,\n ): Promise<FetchedResource | undefined> {\n // Checked before `ok`, which a 304 is not: nothing changed, so the body\n // that was sent with the validator is still the answer.\n if (response.status === 304) {\n if (known === undefined) {\n // Nothing here asked for it, so nothing here can satisfy it — an\n // intermediary added a validator of its own. Reported on its own terms\n // rather than left to fall through as an unexplained failed status.\n throw await toPokenodeError(\n response,\n `Request to ${response.url} was answered 304, but this client holds no response to reuse`,\n );\n }\n\n // RFC 9110 lets a 304 carry a validator of its own, and a server that\n // re-encodes an unchanged body rotates it. Keeping the one that was sent\n // would spend the next revalidation on a full body.\n const refreshed = response.headers.get(\"ETag\");\n\n if (refreshed !== null && refreshed !== known.etag) {\n this.state.etags?.set(url, { etag: refreshed, value: known.value });\n }\n\n await this.state.cache?.set(url, known.value);\n\n return { data: known.value, status: response.status, revalidated: true };\n }\n\n if (!response.ok) {\n return undefined;\n }\n\n const data: unknown = await response.json();\n const etag = response.headers.get(\"ETag\");\n\n if (etag !== null) {\n this.state.etags?.set(url, { etag, value: data });\n }\n\n await this.state.cache?.set(url, data);\n\n return { data, status: response.status };\n }\n\n /**\n * The one place a resolution is accounted for, however it was resolved — which\n * is what keeps {@link Transport.stats} and the response log saying the same\n * thing about the same request.\n */\n private recordResponse(\n url: string,\n status: number,\n source: LogResponsePayload[\"source\"],\n startedAt: number,\n ): void {\n this.state.counts[source] += 1;\n\n this.config.logger?.debug({\n event: \"response\",\n ...logMessage(\"pokeapi response\"),\n url,\n status,\n source,\n durationMs: performance.now() - startedAt,\n });\n }\n}\n","import type { CacheStore, EtagStore } from \"../config/cache\";\nimport type { Logger } from \"../config/logger\";\nimport type { Endpoint } from \"../constants\";\nimport { Transport } from \"../internal/transport\";\nimport type {\n APIResource,\n APIResourceList,\n NamedAPIResource,\n NamedAPIResourceList,\n} from \"../models/common/resource\";\n\n/**\n * ## Fetch Like\n * A `fetch` implementation taking a string URL, as every client call does.\n */\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\n/**\n * ## Resource Link\n * Something naming a single resource: a link taken from a response, or its URL\n * as a bare string.\n *\n * A link carries what it points at, so passing one infers `T`; a string does\n * not, and needs `T` named.\n */\nexport type ResourceLink<T> = string | NamedAPIResource<T> | APIResource<T>;\n\n/**\n * ## Retry Options\n * When a failed request is worth attempting again.\n *\n * Retrying is off unless this is given — a client that quietly triples its own\n * traffic is not something to opt out of after the fact.\n */\nexport interface RetryOptions {\n /** Attempts in total, the first one included. Defaults to 3. */\n attempts?: number;\n /** Statuses worth another attempt. Defaults to 429, 500, 502, 503 and 504. */\n statuses?: number[];\n /** The first wait, in milliseconds, doubling from there. Defaults to 300. */\n initialDelay?: number;\n /** The longest this client will ever wait between attempts. Defaults to 5000. */\n maxDelay?: number;\n}\n\n/**\n * ## Request Scope\n * Cancellation applied to every request a client makes.\n *\n * Passed to {@link ClientFacade.with}, not to the constructor: a signal belongs\n * to one unit of work, while a client outlives many, and a client holding a\n * signal for its whole life is dead the first time that signal aborts.\n */\nexport interface RequestScope {\n /** Aborts the requests made through this scope. */\n signal?: AbortSignal;\n /** How long a request may take, in milliseconds, before it is aborted. */\n timeout?: number;\n}\n\n/**\n * ## Client Options\n * Optional configuration accepted by every client.\n */\nexport interface ClientOptions {\n /**\n * Where the request lifecycle is reported. Leave empty to log nothing, or pass\n * {@link consoleLogger} to write it to the console.\n */\n logger?: Logger;\n /**\n * Response cache. Leave empty for an in-memory {@link MemoryCache}, pass `false`\n * to disable caching, or supply your own {@link CacheStore}.\n */\n cache?: CacheStore | false;\n /** Location of the PokéAPI. Leave empty to use the official PokéAPI instance. */\n baseURL?: string;\n /**\n * Custom `fetch` implementation, for proxies, retries, cancellation or\n * instrumentation. Defaults to the global `fetch`.\n *\n * Requests carry no timeout of their own: derive a scoped client with\n * {@link ClientFacade.with} if you want one.\n */\n fetch?: FetchLike;\n /**\n * When to attempt a failed request again. Leave empty to attempt each request\n * exactly once.\n */\n retry?: RetryOptions;\n /**\n * Ask the PokéAPI whether a response has changed, rather than downloading it\n * again, once the {@link CacheStore} entry for it has expired.\n *\n * Pass `true` for a default {@link EtagStore}, or one of your own to size it.\n * Leave empty and every expired entry is refetched in full.\n */\n revalidate?: boolean | EtagStore;\n}\n\n/**\n * ## Client Stats\n * How many resolutions came from where, since the client was built.\n *\n * One count per `source` a {@link LogResponsePayload} reports, which is the only\n * thing that tells a cache hit from a revalidation from a real round trip once\n * the promise has settled. A failed request is counted by neither: it resolved\n * nothing, and it is the logger's `error` event that has it.\n */\nexport interface ClientStats {\n /** Responses downloaded in full. */\n network: number;\n /** Responses answered from the {@link CacheStore}, with no request made. */\n cache: number;\n /** Callers that joined a request already on the wire rather than repeating it. */\n inFlight: number;\n /** Responses the PokéAPI answered `304` for, served from the {@link EtagStore}. */\n revalidated: number;\n /**\n * Requests that left the process — what the PokéAPI actually saw.\n *\n * Not `network + revalidated`. A revalidation is a round trip that saved a\n * body rather than a request that never happened, so it is in here; and a\n * resolution the `retry` option attempted three times is one `network` and\n * three of these. The attempts are the half a caller cannot see, and they are\n * the half that shows up in someone else's rate limit.\n */\n roundTrips: number;\n}\n\n/**\n * ## List Page\n * The part of a resource list a walk needs: how much there is, and this page of\n * it. Both {@link NamedAPIResourceList} and {@link APIResourceList} qualify.\n */\nexport interface ListPage<L> {\n count: number;\n results: L[];\n}\n\n/**\n * ## List Fn\n * A list method, called with the offset and the limit of the page to fetch.\n */\nexport type ListFn<L> = (offset: number, limit: number) => Promise<ListPage<L>>;\n\n/**\n * ## List Method\n * The shape every `list*` method on a section client has.\n */\nexport type ListMethod = (\n offset?: number,\n limit?: number,\n) => Promise<ListPage<APIResource<unknown>>>;\n\n/**\n * ## List Method Name\n * The names of `C`'s own list methods, and nothing else — so naming one to\n * {@link BaseClient.paginate} is checked and completed by the compiler.\n */\nexport type ListMethodName<C> = {\n [K in keyof C]: C[K] extends ListMethod ? K : never;\n}[keyof C];\n\n/** What a list method's page is made of. */\nexport type Listed<F> = F extends (offset?: number, limit?: number) => Promise<ListPage<infer L>>\n ? L\n : never;\n\n/** What a listed link resolves to. */\nexport type Resolves<L> = L extends APIResource<infer T> ? T : never;\n\n/**\n * ## Paginate Options\n * How {@link BaseClient.paginate} walks a list endpoint.\n */\nexport interface PaginateOptions {\n /** Entries fetched per request. Defaults to 20. */\n pageSize?: number;\n /** Fetch each link and yield the resource instead. Defaults to `false`. */\n resolve?: boolean;\n /** Links resolved at a time, when `resolve` is set. Defaults to 4. */\n concurrency?: number;\n}\n\n/**\n * ## Resolve Options\n * How {@link ClientFacade.resolveAll} fetches the links it was given.\n */\nexport interface ResolveOptions {\n /** Links fetched at a time. Defaults to 4. */\n concurrency?: number;\n}\n\n/**\n * ## Client Facade\n * What every client is, underneath: something that owns a transport and talks\n * to it. Holds the members {@link BaseClient} and {@link MainClient} would\n * otherwise each declare — the cache, the scope, and following a link.\n *\n * The transport is a `#private` field rather than a `protected` one so that\n * nothing about it reaches the published types: a `protected` member keeps its\n * type in the emitted `.d.ts`, which would put the whole internal transport\n * surface in front of consumers who cannot name it.\n */\nexport abstract class ClientFacade {\n readonly #transport: Transport;\n\n constructor(options?: ClientOptions);\n /** @internal Shares the transport a client already holds. */\n constructor(source?: ClientOptions | Transport);\n constructor(source?: ClientOptions | Transport) {\n this.#transport = source instanceof Transport ? source : Transport.create(source);\n }\n\n /** The store backing this client, or `undefined` when caching is disabled. */\n public get cache(): CacheStore | undefined {\n return this.#transport.cache;\n }\n\n /**\n * How many resolutions came from where.\n *\n * ```ts\n * await api.pokemon.getPokemonByName('luxray');\n * await api.pokemon.getPokemonByName('luxray');\n *\n * api.stats; // { network: 1, cache: 1, inFlight: 0, revalidated: 0, roundTrips: 1 }\n * ```\n *\n * The counts are the transport's, so they cover every section of a\n * {@link MainClient} and every client derived with {@link ClientFacade.with} —\n * the same sharing that makes one cache serve all of them.\n *\n * A snapshot, read at the moment it is asked for. Keeping one to compare\n * against later means keeping the object, not the client.\n */\n public get stats(): ClientStats {\n return this.#transport.stats;\n }\n\n /**\n * What has been counted since `snapshot` was taken.\n *\n * ```ts\n * const before = api.stats;\n * await renderTeam();\n *\n * api.statsSince(before).roundTrips; // what that render cost\n * ```\n *\n * There is no way to reset the counts, and this is why: the transport behind\n * them is shared by every section of a {@link MainClient} and by every client\n * derived with {@link ClientFacade.with}, so zeroing it for one measurement\n * zeroes it for whatever else is measuring. Subtraction is the same answer\n * without the shared mutation.\n */\n public statsSince(snapshot: ClientStats): ClientStats {\n const now = this.#transport.stats;\n\n return {\n network: now.network - snapshot.network,\n cache: now.cache - snapshot.cache,\n inFlight: now.inFlight - snapshot.inFlight,\n revalidated: now.revalidated - snapshot.revalidated,\n roundTrips: now.roundTrips - snapshot.roundTrips,\n };\n }\n\n /**\n * Derives a client whose requests carry a signal, a timeout, or both.\n *\n * The clone shares this client's transport — its cache, its validators and the\n * requests already on the wire — so a scoped call still joins an identical\n * unscoped one instead of repeating it. Cloning is cheap, but not free: derive\n * one per unit of work — a request handler, a job — rather than one per call.\n *\n * ```ts\n * const scoped = api.with({ signal: request.signal, timeout: 2_000 });\n * ```\n */\n public with(scope: RequestScope): this {\n // Rebuilt through the constructor rather than copied, so that whatever a\n // subclass sets up is initialised instead of skipped — the twelve sections\n // `MainClient` builds, for one. Every constructor down here takes the same\n // `ClientOptions | Transport`, which is what makes the cast hold.\n const Client = this.constructor as new (transport: Transport) => this;\n\n return new Client(this.#transport.with(scope));\n }\n\n /**\n * Drops every cached response, and any `ETag` learned for one — otherwise the\n * next request revalidates and is answered with the body just dropped.\n *\n * A {@link CacheStore} that does not implement `clear` is left alone.\n *\n * The store is the transport's, so a client sharing one with others clears\n * theirs too.\n */\n public async clearCache(): Promise<void> {\n await this.#transport.clear();\n }\n\n /**\n * Fetches what a link points at, through this client's cache and scope.\n *\n * A link carries what it points at, so the result is typed without saying so:\n *\n * ```ts\n * const pokemon = await api.getPokemonByName('luxray');\n * const species = await api.resolve(pokemon.species);\n * // ^? PokemonSpecies\n * ```\n *\n * A link names a resource, not a section, so any client resolves any link.\n *\n * @throws {TypeError} If the URL is not valid, or names no PokéAPI endpoint.\n */\n public async resolve<T>(resource: ResourceLink<T>): Promise<T> {\n return this.#transport.byURL<T>(resource);\n }\n\n /**\n * Fetches what several links point at, in the order they were given.\n *\n * At most `concurrency` requests run at a time — four by default, because the\n * PokéAPI's fair-use policy asks clients not to flood it. The first failure\n * rejects, and no further link is fetched.\n *\n * ```ts\n * const types = await api.resolveAll(pokemon.types.map((slot) => slot.type));\n * // ^? Type[]\n * ```\n */\n public async resolveAll<T>(\n resources: readonly ResourceLink<T>[],\n options?: ResolveOptions,\n ): Promise<T[]> {\n return this.#transport.resolveAll<T>(resources, options?.concurrency);\n }\n\n /**\n * Retrieves a single resource from the PokéAPI by its endpoint and identifier.\n *\n * @param segments - The identifier of the resource, followed by any path below\n * it. Each is percent-encoded, so pass `id, 'encounters'` rather than\n * `` `${id}/encounters` ``. Omit them to address the endpoint itself.\n */\n protected async getResource<T>(endpoint: Endpoint, ...segments: (string | number)[]): Promise<T> {\n return this.#transport.resource<T>(endpoint, ...segments);\n }\n\n /**\n * Retrieves a resource by its URL, or by a link taken from another response.\n *\n * A link knows what it points at, so passing one infers `T`; a bare string\n * does not, and needs `T` named.\n *\n * @throws {TypeError} If the URL is not valid, or names no endpoint under `baseURL`.\n */\n protected async getResourceByURL<T>(resource: ResourceLink<T>, baseURL?: string): Promise<T> {\n return this.#transport.byURL<T>(resource, baseURL);\n }\n\n /**\n * Retrieves a list of resources from the PokéAPI with pagination support.\n *\n * @template T - What the listed links resolve to.\n */\n protected async getListResource<T = unknown>(\n endpoint: Endpoint,\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<T>> {\n return this.#transport.list<NamedAPIResourceList<T>>(endpoint, offset, limit);\n }\n\n /**\n * Retrieves a list of resources that have no name to list, with pagination support.\n *\n * @template T - What the listed links resolve to.\n */\n protected async getUnnamedListResource<T = unknown>(\n endpoint: Endpoint,\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<T>> {\n return this.#transport.list<APIResourceList<T>>(endpoint, offset, limit);\n }\n\n /**\n * Walks every page of a list, yielding one entry at a time. The bridge\n * {@link BaseClient.paginate} reaches the transport through, so that no\n * signature here has to name one.\n */\n protected walk<T>(\n list: ListFn<APIResource<T>>,\n options?: PaginateOptions,\n ): AsyncGenerator<APIResource<T> | T> {\n return this.#transport.walk(list, options);\n }\n}\n\n/**\n * ## Base Client\n * Base class for every section client. Names endpoints; the transport behind\n * {@link ClientFacade} does everything else — requests, caching, coalescing,\n * retries and logs.\n *\n * A {@link MainClient} builds one transport and hands it to all twelve of its\n * section clients, which is what makes them share a cache and a round trip.\n */\nexport class BaseClient extends ClientFacade {\n /**\n * Walks every page of a list endpoint, yielding one entry at a time.\n *\n * Name the list method to walk; the offset and the limit are this method's to\n * manage.\n *\n * ```ts\n * for await (const berry of api.berry.paginate('listBerries')) {\n * console.log(berry.name);\n * }\n * ```\n *\n * With `resolve`, each link is fetched and the resource is yielded instead of\n * the link. Requests are capped at `concurrency` at a time — the default is\n * deliberately low, because walking a section is exactly the traffic the\n * PokéAPI's fair-use policy asks clients to keep gentle.\n *\n * ```ts\n * for await (const berry of api.berry.paginate('listBerries', { resolve: true })) {\n * console.log(berry.growth_time);\n * }\n * ```\n *\n * A function is accepted too, for a list this client does not carry — a page\n * of a foreign endpoint, or one narrowed before the walk sees it.\n *\n * ```ts\n * api.berry.paginate((offset, limit) => api.berry.listBerries(offset, limit));\n * ```\n */\n public paginate<K extends ListMethodName<this>>(\n list: K,\n options?: PaginateOptions & { resolve?: false },\n ): AsyncGenerator<Listed<this[K]>>;\n public paginate<K extends ListMethodName<this>>(\n list: K,\n options: PaginateOptions & { resolve: true },\n ): AsyncGenerator<Resolves<Listed<this[K]>>>;\n public paginate<L extends APIResource<unknown>>(\n list: ListFn<L>,\n options?: PaginateOptions & { resolve?: false },\n ): AsyncGenerator<L>;\n public paginate<T>(\n list: ListFn<APIResource<T>>,\n options: PaginateOptions & { resolve: true },\n ): AsyncGenerator<T>;\n public paginate<T>(\n list: ListFn<APIResource<T>> | ListMethodName<this>,\n options?: PaginateOptions,\n ): AsyncGenerator<APIResource<T> | T> {\n // A named method is bound here rather than by the caller: reaching it\n // through `this` is the whole point of naming it, and `this` is what\n // carries the scope a derived client was given.\n const listPage =\n typeof list === \"function\"\n ? list\n : (offset: number, limit: number) => (this[list] as ListFn<APIResource<T>>)(offset, limit);\n\n return this.walk(listPage, options);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Berry, BerryFirmness, BerryFlavor, NamedAPIResourceList } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Berry Client\n *\n * Client used to access the Berry Endpoints:\n *\n * - [Berries](https://pokeapi.co/docs/v2#berries)\n * - [Berry Firmnesses](https://pokeapi.co/docs/v2#berry-firmnesses)\n * - [Berry Flavors](https://pokeapi.co/docs/v2#berry-flavors)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#berries-section)\n */\nexport class BerryClient extends BaseClient {\n /** Get a Berry by its name. */\n public async getBerryByName(name: string): Promise<Berry> {\n return this.getResource(ENDPOINTS.BERRY, name);\n }\n\n /** Get a Berry by its ID. */\n public async getBerryById(id: number): Promise<Berry> {\n return this.getResource(ENDPOINTS.BERRY, id);\n }\n\n /** Get a Berry Firmness by its ID. */\n public async getBerryFirmnessById(id: number): Promise<BerryFirmness> {\n return this.getResource(ENDPOINTS.BERRY_FIRMNESS, id);\n }\n\n /** Get a Berry Firmness by its name. */\n public async getBerryFirmnessByName(name: string): Promise<BerryFirmness> {\n return this.getResource(ENDPOINTS.BERRY_FIRMNESS, name);\n }\n\n /** Get a Berry Flavor by its ID. */\n public async getBerryFlavorById(id: number): Promise<BerryFlavor> {\n return this.getResource(ENDPOINTS.BERRY_FLAVOR, id);\n }\n\n /** Get a Berry Flavor by its name. */\n public async getBerryFlavorByName(name: string): Promise<BerryFlavor> {\n return this.getResource(ENDPOINTS.BERRY_FLAVOR, name);\n }\n\n /** List Berries. Page defaults to 20 entries from offset 0. */\n public async listBerries(offset?: number, limit?: number): Promise<NamedAPIResourceList<Berry>> {\n return this.getListResource<Berry>(ENDPOINTS.BERRY, offset, limit);\n }\n\n /** List Berry Firmnesses. Page defaults to 20 entries from offset 0. */\n public async listBerryFirmnesses(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<BerryFirmness>> {\n return this.getListResource<BerryFirmness>(ENDPOINTS.BERRY_FIRMNESS, offset, limit);\n }\n\n /** List Berry Flavors. Page defaults to 20 entries from offset 0. */\n public async listBerryFlavors(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<BerryFlavor>> {\n return this.getListResource<BerryFlavor>(ENDPOINTS.BERRY_FLAVOR, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n APIResourceList,\n ContestEffect,\n ContestType,\n NamedAPIResourceList,\n SuperContestEffect,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Contest Client\n *\n * Client used to access the Contest Endpoints:\n *\n * - [Contest Types](https://pokeapi.co/docs/v2#contest-types)\n * - [Contest Effects](https://pokeapi.co/docs/v2#contest-effects)\n * - [Super Contest Effects](https://pokeapi.co/docs/v2#super-contest-effects)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#contests-section)\n */\nexport class ContestClient extends BaseClient {\n /** Get a Contest Type by its name. */\n public async getContestTypeByName(name: string): Promise<ContestType> {\n return this.getResource(ENDPOINTS.CONTEST_TYPE, name);\n }\n\n /** Get a Contest Type by its ID. */\n public async getContestTypeById(id: number): Promise<ContestType> {\n return this.getResource(ENDPOINTS.CONTEST_TYPE, id);\n }\n\n /** Get a Contest Effect by its ID. */\n public async getContestEffectById(id: number): Promise<ContestEffect> {\n return this.getResource(ENDPOINTS.CONTEST_EFFECT, id);\n }\n\n /** Get a Super Contest Effect by its ID. */\n public async getSuperContestEffectById(id: number): Promise<SuperContestEffect> {\n return this.getResource(ENDPOINTS.SUPER_CONTEST_EFFECT, id);\n }\n\n /** List Contest Types. Page defaults to 20 entries from offset 0. */\n public async listContestTypes(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ContestType>> {\n return this.getListResource<ContestType>(ENDPOINTS.CONTEST_TYPE, offset, limit);\n }\n\n /** List Contest Effects. Page defaults to 20 entries from offset 0. */\n public async listContestEffects(\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<ContestEffect>> {\n return this.getUnnamedListResource<ContestEffect>(ENDPOINTS.CONTEST_EFFECT, offset, limit);\n }\n\n /** List Super Contest Effects. Page defaults to 20 entries from offset 0. */\n public async listSuperContestEffects(\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<SuperContestEffect>> {\n return this.getUnnamedListResource<SuperContestEffect>(\n ENDPOINTS.SUPER_CONTEST_EFFECT,\n offset,\n limit,\n );\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Currency, NamedAPIResourceList } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Currency Client\n *\n * Client used to access the Currency Endpoints:\n *\n * - [Currencies](https://pokeapi.co/docs/v2#currencies)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#currencies-section)\n */\nexport class CurrencyClient extends BaseClient {\n /** Get a Currency by its name. */\n public async getCurrencyByName(name: string): Promise<Currency> {\n return this.getResource(ENDPOINTS.CURRENCY, name);\n }\n\n /** Get a Currency by its ID. */\n public async getCurrencyById(id: number): Promise<Currency> {\n return this.getResource(ENDPOINTS.CURRENCY, id);\n }\n\n /** List Currencies. Page defaults to 20 entries from offset 0. */\n public async listCurrencies(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Currency>> {\n return this.getListResource<Currency>(ENDPOINTS.CURRENCY, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n EncounterCondition,\n EncounterConditionValue,\n EncounterMethod,\n NamedAPIResourceList,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Encounter Client\n *\n * Client used to access the Encounter Endpoints:\n *\n * - [Encounter Methods](https://pokeapi.co/docs/v2#encounter-methods)\n * - [Encounter Conditions](https://pokeapi.co/docs/v2#encounter-conditions)\n * - [Encounter Condition Values](https://pokeapi.co/docs/v2#encounter-condition-values)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#encounters-section)\n */\nexport class EncounterClient extends BaseClient {\n /** Get an Encounter Method by its name. */\n public async getEncounterMethodByName(name: string): Promise<EncounterMethod> {\n return this.getResource<EncounterMethod>(ENDPOINTS.ENCOUNTER_METHOD, name);\n }\n\n /** Get an Encounter Method by its ID. */\n public async getEncounterMethodById(id: number): Promise<EncounterMethod> {\n return this.getResource<EncounterMethod>(ENDPOINTS.ENCOUNTER_METHOD, id);\n }\n\n /** Get an Encounter Condition by its ID. */\n public async getEncounterConditionById(id: number): Promise<EncounterCondition> {\n return this.getResource<EncounterCondition>(ENDPOINTS.ENCOUNTER_CONDITION, id);\n }\n\n /** Get an Encounter Condition by its name. */\n public async getEncounterConditionByName(name: string): Promise<EncounterCondition> {\n return this.getResource<EncounterCondition>(ENDPOINTS.ENCOUNTER_CONDITION, name);\n }\n\n /** Get an Encounter Condition Value by its name. */\n public async getEncounterConditionValueByName(name: string): Promise<EncounterConditionValue> {\n return this.getResource<EncounterConditionValue>(ENDPOINTS.ENCOUNTER_CONDITION_VALUE, name);\n }\n\n /** Get an Encounter Condition Value by its ID. */\n public async getEncounterConditionValueById(id: number): Promise<EncounterConditionValue> {\n return this.getResource<EncounterConditionValue>(ENDPOINTS.ENCOUNTER_CONDITION_VALUE, id);\n }\n\n /** List Encounter Methods. Page defaults to 20 entries from offset 0. */\n public async listEncounterMethods(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EncounterMethod>> {\n return this.getListResource<EncounterMethod>(ENDPOINTS.ENCOUNTER_METHOD, offset, limit);\n }\n\n /** List Encounter Conditions. Page defaults to 20 entries from offset 0. */\n public async listEncounterConditions(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EncounterCondition>> {\n return this.getListResource<EncounterCondition>(ENDPOINTS.ENCOUNTER_CONDITION, offset, limit);\n }\n\n /** List Encounter Condition Values. Page defaults to 20 entries from offset 0. */\n public async listEncounterConditionValues(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EncounterConditionValue>> {\n return this.getListResource<EncounterConditionValue>(\n ENDPOINTS.ENCOUNTER_CONDITION_VALUE,\n offset,\n limit,\n );\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n APIResourceList,\n EvolutionChain,\n EvolutionTrigger,\n NamedAPIResourceList,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Evolution Client\n *\n * Client used to access the Evolution Endpoints:\n *\n * - [Evolution Chains](https://pokeapi.co/docs/v2#evolution-chains)\n * - [Evolution Triggers](https://pokeapi.co/docs/v2#evolution-triggers)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#evolution-section)\n */\nexport class EvolutionClient extends BaseClient {\n /** Get an Evolution Chain by its ID. */\n public async getEvolutionChainById(id: number): Promise<EvolutionChain> {\n return this.getResource(ENDPOINTS.EVOLUTION_CHAIN, id);\n }\n\n /** Get an Evolution Trigger by its ID. */\n public async getEvolutionTriggerById(id: number): Promise<EvolutionTrigger> {\n return this.getResource(ENDPOINTS.EVOLUTION_TRIGGER, id);\n }\n\n /** Get an Evolution Trigger by its name. */\n public async getEvolutionTriggerByName(name: string): Promise<EvolutionTrigger> {\n return this.getResource(ENDPOINTS.EVOLUTION_TRIGGER, name);\n }\n\n /** List Evolution Chains. Page defaults to 20 entries from offset 0. */\n public async listEvolutionChains(\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<EvolutionChain>> {\n return this.getUnnamedListResource<EvolutionChain>(ENDPOINTS.EVOLUTION_CHAIN, offset, limit);\n }\n\n /** List Evolution Triggers. Page defaults to 20 entries from offset 0. */\n public async listEvolutionTriggers(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EvolutionTrigger>> {\n return this.getListResource<EvolutionTrigger>(ENDPOINTS.EVOLUTION_TRIGGER, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Generation, NamedAPIResourceList, Pokedex, Version, VersionGroup } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Game Client\n *\n * Client used to access the Game Endpoints:\n *\n * - [Generations](https://pokeapi.co/docs/v2#generations)\n * - [Pokédexes](https://pokeapi.co/docs/v2#pokedexes)\n * - [Versions](https://pokeapi.co/docs/v2#version)\n * - [Version Groups](https://pokeapi.co/docs/v2#version-groups)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#games-section)\n */\nexport class GameClient extends BaseClient {\n /** Get a Generation by its name. */\n public async getGenerationByName(name: string): Promise<Generation> {\n return this.getResource(ENDPOINTS.GENERATION, name);\n }\n\n /** Get a Generation by its ID. */\n public async getGenerationById(id: number): Promise<Generation> {\n return this.getResource(ENDPOINTS.GENERATION, id);\n }\n\n /** Get a Pokédex by its name. */\n public async getPokedexByName(name: string): Promise<Pokedex> {\n return this.getResource(ENDPOINTS.POKEDEX, name);\n }\n\n /** Get a Pokédex by its ID. */\n public async getPokedexById(id: number): Promise<Pokedex> {\n return this.getResource(ENDPOINTS.POKEDEX, id);\n }\n\n /** Get a Version by its name. */\n public async getVersionByName(name: string): Promise<Version> {\n return this.getResource(ENDPOINTS.VERSION, name);\n }\n\n /** Get a Version by its ID. */\n public async getVersionById(id: number): Promise<Version> {\n return this.getResource(ENDPOINTS.VERSION, id);\n }\n\n /** Get a Version Group by its name. */\n public async getVersionGroupByName(name: string): Promise<VersionGroup> {\n return this.getResource(ENDPOINTS.VERSION_GROUP, name);\n }\n\n /** Get a Version Group by its ID. */\n public async getVersionGroupById(id: number): Promise<VersionGroup> {\n return this.getResource(ENDPOINTS.VERSION_GROUP, id);\n }\n\n /** List Generations. Page defaults to 20 entries from offset 0. */\n public async listGenerations(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Generation>> {\n return this.getListResource<Generation>(ENDPOINTS.GENERATION, offset, limit);\n }\n\n /** List Pokédexes. Page defaults to 20 entries from offset 0. */\n public async listPokedexes(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Pokedex>> {\n return this.getListResource<Pokedex>(ENDPOINTS.POKEDEX, offset, limit);\n }\n\n /** List Versions. Page defaults to 20 entries from offset 0. */\n public async listVersions(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Version>> {\n return this.getListResource<Version>(ENDPOINTS.VERSION, offset, limit);\n }\n\n /** List Version Groups. Page defaults to 20 entries from offset 0. */\n public async listVersionGroups(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<VersionGroup>> {\n return this.getListResource<VersionGroup>(ENDPOINTS.VERSION_GROUP, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n Item,\n ItemAttribute,\n ItemCategory,\n ItemFlingEffect,\n ItemPocket,\n NamedAPIResourceList,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Item Client\n *\n * Client used to access the Item Endpoints:\n *\n * - [Items](https://pokeapi.co/docs/v2#item)\n * - [Item Attributes](https://pokeapi.co/docs/v2#item-attributes)\n * - [Item Categories](https://pokeapi.co/docs/v2#item-categories)\n * - [Item Fling Effects](https://pokeapi.co/docs/v2#item-fling-effects)\n * - [Item Pockets](https://pokeapi.co/docs/v2#item-pockets)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#items-section)\n */\nexport class ItemClient extends BaseClient {\n /** Get an Item by its name. */\n public async getItemByName(name: string): Promise<Item> {\n return this.getResource(ENDPOINTS.ITEM, name);\n }\n\n /** Get an Item by its ID. */\n public async getItemById(id: number): Promise<Item> {\n return this.getResource(ENDPOINTS.ITEM, id);\n }\n\n /** Get an Item Attribute by its name. */\n public async getItemAttributeByName(name: string): Promise<ItemAttribute> {\n return this.getResource(ENDPOINTS.ITEM_ATTRIBUTE, name);\n }\n\n /** Get an Item Attribute by its ID. */\n public async getItemAttributeById(id: number): Promise<ItemAttribute> {\n return this.getResource(ENDPOINTS.ITEM_ATTRIBUTE, id);\n }\n\n /** Get an Item Category by its name. */\n public async getItemCategoryByName(name: string): Promise<ItemCategory> {\n return this.getResource(ENDPOINTS.ITEM_CATEGORY, name);\n }\n\n /** Get an Item Category by its ID. */\n public async getItemCategoryById(id: number): Promise<ItemCategory> {\n return this.getResource(ENDPOINTS.ITEM_CATEGORY, id);\n }\n\n /** Get an Item Fling Effect by its name. */\n public async getItemFlingEffectByName(name: string): Promise<ItemFlingEffect> {\n return this.getResource(ENDPOINTS.ITEM_FLING_EFFECT, name);\n }\n\n /** Get an Item Fling Effect by its ID. */\n public async getItemFlingEffectById(id: number): Promise<ItemFlingEffect> {\n return this.getResource(ENDPOINTS.ITEM_FLING_EFFECT, id);\n }\n\n /** Get an Item Pocket by its name. */\n public async getItemPocketByName(name: string): Promise<ItemPocket> {\n return this.getResource(ENDPOINTS.ITEM_POCKET, name);\n }\n\n /** Get an Item Pocket by its ID. */\n public async getItemPocketById(id: number): Promise<ItemPocket> {\n return this.getResource(ENDPOINTS.ITEM_POCKET, id);\n }\n\n /** List Items. Page defaults to 20 entries from offset 0. */\n public async listItems(offset?: number, limit?: number): Promise<NamedAPIResourceList<Item>> {\n return this.getListResource<Item>(ENDPOINTS.ITEM, offset, limit);\n }\n\n /** List Item Attributes. Page defaults to 20 entries from offset 0. */\n public async listItemAttributes(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ItemAttribute>> {\n return this.getListResource<ItemAttribute>(ENDPOINTS.ITEM_ATTRIBUTE, offset, limit);\n }\n\n /** List Item Categories. Page defaults to 20 entries from offset 0. */\n public async listItemCategories(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ItemCategory>> {\n return this.getListResource<ItemCategory>(ENDPOINTS.ITEM_CATEGORY, offset, limit);\n }\n\n /** List Item Fling Effects. Page defaults to 20 entries from offset 0. */\n public async listItemFlingEffects(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ItemFlingEffect>> {\n return this.getListResource<ItemFlingEffect>(ENDPOINTS.ITEM_FLING_EFFECT, offset, limit);\n }\n\n /** List Item Pockets. Page defaults to 20 entries from offset 0. */\n public async listItemPockets(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<ItemPocket>> {\n return this.getListResource<ItemPocket>(ENDPOINTS.ITEM_POCKET, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Location, LocationArea, NamedAPIResourceList, PalParkArea, Region } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Location Client\n *\n * Client used to access the Location Endpoints:\n *\n * - [Locations](https://pokeapi.co/docs/v2#locations)\n * - [Location Areas](https://pokeapi.co/docs/v2#location-areas)\n * - [Pal Park Areas](https://pokeapi.co/docs/v2#pal-park-areas)\n * - [Regions](https://pokeapi.co/docs/v2#regions)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#locations-section)\n */\nexport class LocationClient extends BaseClient {\n /** Get a Location by its name. */\n public async getLocationByName(name: string): Promise<Location> {\n return this.getResource(ENDPOINTS.LOCATION, name);\n }\n\n /** Get a Location by its ID. */\n public async getLocationById(id: number): Promise<Location> {\n return this.getResource(ENDPOINTS.LOCATION, id);\n }\n\n /** Get a Location Area by its name. */\n public async getLocationAreaByName(name: string): Promise<LocationArea> {\n return this.getResource(ENDPOINTS.LOCATION_AREA, name);\n }\n\n /** Get a Location Area by its ID. */\n public async getLocationAreaById(id: number): Promise<LocationArea> {\n return this.getResource(ENDPOINTS.LOCATION_AREA, id);\n }\n\n /** Get a Pal Park Area by its name. */\n public async getPalParkAreaByName(name: string): Promise<PalParkArea> {\n return this.getResource(ENDPOINTS.PALPARK_AREA, name);\n }\n\n /** Get a Pal Park Area by its ID. */\n public async getPalParkAreaById(id: number): Promise<PalParkArea> {\n return this.getResource(ENDPOINTS.PALPARK_AREA, id);\n }\n\n /** Get a Region by its name. */\n public async getRegionByName(name: string): Promise<Region> {\n return this.getResource(ENDPOINTS.REGION, name);\n }\n\n /** Get a Region by its ID. */\n public async getRegionById(id: number): Promise<Region> {\n return this.getResource(ENDPOINTS.REGION, id);\n }\n\n /** List Locations. Page defaults to 20 entries from offset 0. */\n public async listLocations(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Location>> {\n return this.getListResource<Location>(ENDPOINTS.LOCATION, offset, limit);\n }\n\n /** List Location Areas. Page defaults to 20 entries from offset 0. */\n public async listLocationAreas(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<LocationArea>> {\n return this.getListResource<LocationArea>(ENDPOINTS.LOCATION_AREA, offset, limit);\n }\n\n /** List Pal Park Areas. Page defaults to 20 entries from offset 0. */\n public async listPalParkAreas(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PalParkArea>> {\n return this.getListResource<PalParkArea>(ENDPOINTS.PALPARK_AREA, offset, limit);\n }\n\n /** List Regions. Page defaults to 20 entries from offset 0. */\n public async listRegions(offset?: number, limit?: number): Promise<NamedAPIResourceList<Region>> {\n return this.getListResource<Region>(ENDPOINTS.REGION, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { APIResourceList, Machine } from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Machine Client\n *\n * Client used to access the Machine Endpoints:\n *\n * - [Machines](https://pokeapi.co/docs/v2#machines)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#machines-section)\n */\nexport class MachineClient extends BaseClient {\n /** Get a Machine by its ID. */\n public async getMachineById(id: number): Promise<Machine> {\n return this.getResource(ENDPOINTS.MACHINE, id);\n }\n\n /** List Machines. Page defaults to 20 entries from offset 0. */\n public async listMachines(offset?: number, limit?: number): Promise<APIResourceList<Machine>> {\n return this.getUnnamedListResource<Machine>(ENDPOINTS.MACHINE, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n Move,\n MoveAilment,\n MoveBattleStyle,\n MoveCategory,\n MoveDamageClass,\n MoveLearnMethod,\n MoveTarget,\n NamedAPIResourceList,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Move Client\n *\n * Client used to access the Move Endpoints:\n *\n * - [Moves](https://pokeapi.co/docs/v2#moves)\n * - [Move Ailments](https://pokeapi.co/docs/v2#move-ailments)\n * - [Move Battle Styles](https://pokeapi.co/docs/v2#move-battle-styles)\n * - [Move Categories](https://pokeapi.co/docs/v2#move-categories)\n * - [Move Damage Classes](https://pokeapi.co/docs/v2#move-damage-classes)\n * - [Move Learn Methods](https://pokeapi.co/docs/v2#move-learn-methods)\n * - [Move Targets](https://pokeapi.co/docs/v2#move-targets)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#moves-section)\n */\nexport class MoveClient extends BaseClient {\n /** Get a Move by its name. */\n public async getMoveByName(name: string): Promise<Move> {\n return this.getResource(ENDPOINTS.MOVE, name);\n }\n\n /** Get a Move by its ID. */\n public async getMoveById(id: number): Promise<Move> {\n return this.getResource(ENDPOINTS.MOVE, id);\n }\n\n /** Get a Move Ailment by its name. */\n public async getMoveAilmentByName(name: string): Promise<MoveAilment> {\n return this.getResource(ENDPOINTS.MOVE_AILMENT, name);\n }\n\n /** Get a Move Ailment by its ID. */\n public async getMoveAilmentById(id: number): Promise<MoveAilment> {\n return this.getResource(ENDPOINTS.MOVE_AILMENT, id);\n }\n\n /** Get a Move Battle Style by its name. */\n public async getMoveBattleStyleByName(name: string): Promise<MoveBattleStyle> {\n return this.getResource(ENDPOINTS.MOVE_BATTLE_STYLE, name);\n }\n\n /** Get a Move Battle Style by its ID. */\n public async getMoveBattleStyleById(id: number): Promise<MoveBattleStyle> {\n return this.getResource(ENDPOINTS.MOVE_BATTLE_STYLE, id);\n }\n\n /** Get a Move Category by its name. */\n public async getMoveCategoryByName(name: string): Promise<MoveCategory> {\n return this.getResource(ENDPOINTS.MOVE_CATEGORY, name);\n }\n\n /** Get a Move Category by its ID. */\n public async getMoveCategoryById(id: number): Promise<MoveCategory> {\n return this.getResource(ENDPOINTS.MOVE_CATEGORY, id);\n }\n\n /** Get a Move Damage Class by its name. */\n public async getMoveDamageClassByName(name: string): Promise<MoveDamageClass> {\n return this.getResource(ENDPOINTS.MOVE_DAMAGE_CLASS, name);\n }\n\n /** Get a Move Damage Class by its ID. */\n public async getMoveDamageClassById(id: number): Promise<MoveDamageClass> {\n return this.getResource(ENDPOINTS.MOVE_DAMAGE_CLASS, id);\n }\n\n /** Get a Move Learn Method by its name. */\n public async getMoveLearnMethodByName(name: string): Promise<MoveLearnMethod> {\n return this.getResource(ENDPOINTS.MOVE_LEARN_METHOD, name);\n }\n\n /** Get a Move Learn Method by its ID. */\n public async getMoveLearnMethodById(id: number): Promise<MoveLearnMethod> {\n return this.getResource(ENDPOINTS.MOVE_LEARN_METHOD, id);\n }\n\n /** Get a Move Target by its name. */\n public async getMoveTargetByName(name: string): Promise<MoveTarget> {\n return this.getResource(ENDPOINTS.MOVE_TARGET, name);\n }\n\n /** Get a Move Target by its ID. */\n public async getMoveTargetById(id: number): Promise<MoveTarget> {\n return this.getResource(ENDPOINTS.MOVE_TARGET, id);\n }\n\n /** List Moves. Page defaults to 20 entries from offset 0. */\n public async listMoves(offset?: number, limit?: number): Promise<NamedAPIResourceList<Move>> {\n return this.getListResource<Move>(ENDPOINTS.MOVE, offset, limit);\n }\n\n /** List Move Ailments. Page defaults to 20 entries from offset 0. */\n public async listMoveAilments(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveAilment>> {\n return this.getListResource<MoveAilment>(ENDPOINTS.MOVE_AILMENT, offset, limit);\n }\n\n /** List Move Battle Styles. Page defaults to 20 entries from offset 0. */\n public async listMoveBattleStyles(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveBattleStyle>> {\n return this.getListResource<MoveBattleStyle>(ENDPOINTS.MOVE_BATTLE_STYLE, offset, limit);\n }\n\n /** List Move Categories. Page defaults to 20 entries from offset 0. */\n public async listMoveCategories(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveCategory>> {\n return this.getListResource<MoveCategory>(ENDPOINTS.MOVE_CATEGORY, offset, limit);\n }\n\n /** List Move Damage Classes. Page defaults to 20 entries from offset 0. */\n public async listMoveDamageClasses(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveDamageClass>> {\n return this.getListResource<MoveDamageClass>(ENDPOINTS.MOVE_DAMAGE_CLASS, offset, limit);\n }\n\n /** List Move Learn Methods. Page defaults to 20 entries from offset 0. */\n public async listMoveLearnMethods(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveLearnMethod>> {\n return this.getListResource<MoveLearnMethod>(ENDPOINTS.MOVE_LEARN_METHOD, offset, limit);\n }\n\n /** List Move Targets. Page defaults to 20 entries from offset 0. */\n public async listMoveTargets(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<MoveTarget>> {\n return this.getListResource<MoveTarget>(ENDPOINTS.MOVE_TARGET, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type {\n Ability,\n APIResourceList,\n Characteristic,\n EggGroup,\n Gender,\n GrowthRate,\n LocationAreaEncounter,\n NamedAPIResourceList,\n Nature,\n PokeathlonStat,\n Pokemon,\n PokemonColor,\n PokemonForm,\n PokemonHabitat,\n PokemonShape,\n PokemonSpecies,\n Stat,\n Type,\n} from \"@models\";\nimport { BaseClient } from \"./base\";\n\n/**\n * ### Pokémon Client\n *\n * Client used to access the Pokémon Endpoints:\n *\n * - [Abilities](https://pokeapi.co/docs/v2#abilities)\n * - [Characteristics](https://pokeapi.co/docs/v2#characteristics)\n * - [Egg Groups](https://pokeapi.co/docs/v2#egg-groups)\n * - [Genders](https://pokeapi.co/docs/v2#genders)\n * - [Growth Rates](https://pokeapi.co/docs/v2#growth-rates)\n * - [Natures](https://pokeapi.co/docs/v2#natures)\n * - [Pokéathlon Stats](https://pokeapi.co/docs/v2#pokeathlon-stats)\n * - [Pokémon](https://pokeapi.co/docs/v2#pokemon)\n * - [Pokémon Location Areas](https://pokeapi.co/docs/v2#pokemon-location-areas)\n * - [Pokémon Colors](https://pokeapi.co/docs/v2#pokemon-colors)\n * - [Pokémon Forms](https://pokeapi.co/docs/v2#pokemon-forms)\n * - [Pokémon Habitats](https://pokeapi.co/docs/v2#pokemon-habitats)\n * - [Pokémon Shapes](https://pokeapi.co/docs/v2#pokemon-shapes)\n * - [Pokémon Species](https://pokeapi.co/docs/v2#pokemon-species)\n * - [Stats](https://pokeapi.co/docs/v2#stats)\n * - [Types](https://pokeapi.co/docs/v2#types)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#pokemon-section)\n */\nexport class PokemonClient extends BaseClient {\n /** Get an Ability by its name. */\n public async getAbilityByName(name: string): Promise<Ability> {\n return this.getResource(ENDPOINTS.ABILITY, name);\n }\n\n /** Get an Ability by its ID. */\n public async getAbilityById(id: number): Promise<Ability> {\n return this.getResource(ENDPOINTS.ABILITY, id);\n }\n\n /** Get a Characteristic by its ID. */\n public async getCharacteristicById(id: number): Promise<Characteristic> {\n return this.getResource(ENDPOINTS.CHARACTERISTIC, id);\n }\n\n /** Get an Egg Group by its name. */\n public async getEggGroupByName(name: string): Promise<EggGroup> {\n return this.getResource(ENDPOINTS.EGG_GROUP, name);\n }\n\n /** Get an Egg Group by its ID. */\n public async getEggGroupById(id: number): Promise<EggGroup> {\n return this.getResource(ENDPOINTS.EGG_GROUP, id);\n }\n\n /** Get a Gender by its name. */\n public async getGenderByName(name: string): Promise<Gender> {\n return this.getResource(ENDPOINTS.GENDER, name);\n }\n\n /** Get a Gender by its ID. */\n public async getGenderById(id: number): Promise<Gender> {\n return this.getResource(ENDPOINTS.GENDER, id);\n }\n\n /** Get a Growth Rate by its name. */\n public async getGrowthRateByName(name: string): Promise<GrowthRate> {\n return this.getResource(ENDPOINTS.GROWTH_RATE, name);\n }\n\n /** Get a Growth Rate by its ID. */\n public async getGrowthRateById(id: number): Promise<GrowthRate> {\n return this.getResource(ENDPOINTS.GROWTH_RATE, id);\n }\n\n /** Get a Nature by its name. */\n public async getNatureByName(name: string): Promise<Nature> {\n return this.getResource(ENDPOINTS.NATURE, name);\n }\n\n /** Get a Nature by its ID. */\n public async getNatureById(id: number): Promise<Nature> {\n return this.getResource(ENDPOINTS.NATURE, id);\n }\n\n /** Get a Pokéathlon Stat by its name. */\n public async getPokeathlonStatByName(name: string): Promise<PokeathlonStat> {\n return this.getResource(ENDPOINTS.POKEATHLON_STAT, name);\n }\n\n /** Get a Pokéathlon Stat by its ID. */\n public async getPokeathlonStatById(id: number): Promise<PokeathlonStat> {\n return this.getResource(ENDPOINTS.POKEATHLON_STAT, id);\n }\n\n /** Get a Pokémon by its name. */\n public async getPokemonByName(name: string): Promise<Pokemon> {\n return this.getResource(ENDPOINTS.POKEMON, name);\n }\n\n /** Get a Pokémon by its ID. */\n public async getPokemonById(id: number): Promise<Pokemon> {\n return this.getResource(ENDPOINTS.POKEMON, id);\n }\n\n /**\n * Get the areas a Pokémon can be encountered in, by its ID.\n * @returns Every location area the Pokémon appears in, with its encounter details.\n */\n public async getPokemonLocationAreaById(id: number): Promise<LocationAreaEncounter[]> {\n // Encounters hang off a single Pokémon rather than being an endpoint of\n // their own, so the path below `/pokemon` is addressed directly.\n return this.getResource(ENDPOINTS.POKEMON, id, \"encounters\");\n }\n\n /** Get a Pokémon Color by its name. */\n public async getPokemonColorByName(name: string): Promise<PokemonColor> {\n return this.getResource(ENDPOINTS.POKEMON_COLOR, name);\n }\n\n /** Get a Pokémon Color by its ID. */\n public async getPokemonColorById(id: number): Promise<PokemonColor> {\n return this.getResource(ENDPOINTS.POKEMON_COLOR, id);\n }\n\n /** Get a Pokémon Form by its name. */\n public async getPokemonFormByName(name: string): Promise<PokemonForm> {\n return this.getResource(ENDPOINTS.POKEMON_FORM, name);\n }\n\n /** Get a Pokémon Form by its ID. */\n public async getPokemonFormById(id: number): Promise<PokemonForm> {\n return this.getResource(ENDPOINTS.POKEMON_FORM, id);\n }\n\n /** Get a Pokémon Habitat by its name. */\n public async getPokemonHabitatByName(name: string): Promise<PokemonHabitat> {\n return this.getResource(ENDPOINTS.POKEMON_HABITAT, name);\n }\n\n /** Get a Pokémon Habitat by its ID. */\n public async getPokemonHabitatById(id: number): Promise<PokemonHabitat> {\n return this.getResource(ENDPOINTS.POKEMON_HABITAT, id);\n }\n\n /** Get a Pokémon Shape by its name. */\n public async getPokemonShapeByName(name: string): Promise<PokemonShape> {\n return this.getResource(ENDPOINTS.POKEMON_SHAPE, name);\n }\n\n /** Get a Pokémon Shape by its ID. */\n public async getPokemonShapeById(id: number): Promise<PokemonShape> {\n return this.getResource(ENDPOINTS.POKEMON_SHAPE, id);\n }\n\n /** Get a Pokémon Species by its name. */\n public async getPokemonSpeciesByName(name: string): Promise<PokemonSpecies> {\n return this.getResource(ENDPOINTS.POKEMON_SPECIES, name);\n }\n\n /** Get a Pokémon Species by its ID. */\n public async getPokemonSpeciesById(id: number): Promise<PokemonSpecies> {\n return this.getResource(ENDPOINTS.POKEMON_SPECIES, id);\n }\n\n /** Get a Stat by its name. */\n public async getStatByName(name: string): Promise<Stat> {\n return this.getResource(ENDPOINTS.STAT, name);\n }\n\n /** Get a Stat by its ID. */\n public async getStatById(id: number): Promise<Stat> {\n return this.getResource(ENDPOINTS.STAT, id);\n }\n\n /** Get a Type by its name. */\n public async getTypeByName(name: string): Promise<Type> {\n return this.getResource(ENDPOINTS.TYPE, name);\n }\n\n /** Get a Type by its ID. */\n public async getTypeById(id: number): Promise<Type> {\n return this.getResource(ENDPOINTS.TYPE, id);\n }\n\n /** List Abilities. Page defaults to 20 entries from offset 0. */\n public async listAbilities(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Ability>> {\n return this.getListResource<Ability>(ENDPOINTS.ABILITY, offset, limit);\n }\n\n /** List Characteristics. Page defaults to 20 entries from offset 0. */\n public async listCharacteristics(\n offset?: number,\n limit?: number,\n ): Promise<APIResourceList<Characteristic>> {\n return this.getUnnamedListResource<Characteristic>(ENDPOINTS.CHARACTERISTIC, offset, limit);\n }\n\n /** List Egg Groups. Page defaults to 20 entries from offset 0. */\n public async listEggGroups(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<EggGroup>> {\n return this.getListResource<EggGroup>(ENDPOINTS.EGG_GROUP, offset, limit);\n }\n\n /** List Genders. Page defaults to 20 entries from offset 0. */\n public async listGenders(offset?: number, limit?: number): Promise<NamedAPIResourceList<Gender>> {\n return this.getListResource<Gender>(ENDPOINTS.GENDER, offset, limit);\n }\n\n /** List Growth Rates. Page defaults to 20 entries from offset 0. */\n public async listGrowthRates(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<GrowthRate>> {\n return this.getListResource<GrowthRate>(ENDPOINTS.GROWTH_RATE, offset, limit);\n }\n\n /** List Natures. Page defaults to 20 entries from offset 0. */\n public async listNatures(offset?: number, limit?: number): Promise<NamedAPIResourceList<Nature>> {\n return this.getListResource<Nature>(ENDPOINTS.NATURE, offset, limit);\n }\n\n /** List Pokéathlon Stats. Page defaults to 20 entries from offset 0. */\n public async listPokeathlonStats(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokeathlonStat>> {\n return this.getListResource<PokeathlonStat>(ENDPOINTS.POKEATHLON_STAT, offset, limit);\n }\n\n /** List Pokémon. Page defaults to 20 entries from offset 0. */\n public async listPokemons(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<Pokemon>> {\n return this.getListResource<Pokemon>(ENDPOINTS.POKEMON, offset, limit);\n }\n\n /** List Pokémon Colors. Page defaults to 20 entries from offset 0. */\n public async listPokemonColors(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonColor>> {\n return this.getListResource<PokemonColor>(ENDPOINTS.POKEMON_COLOR, offset, limit);\n }\n\n /** List Pokémon Forms. Page defaults to 20 entries from offset 0. */\n public async listPokemonForms(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonForm>> {\n return this.getListResource<PokemonForm>(ENDPOINTS.POKEMON_FORM, offset, limit);\n }\n\n /** List Pokémon Habitats. Page defaults to 20 entries from offset 0. */\n public async listPokemonHabitats(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonHabitat>> {\n return this.getListResource<PokemonHabitat>(ENDPOINTS.POKEMON_HABITAT, offset, limit);\n }\n\n /** List Pokémon Shapes. Page defaults to 20 entries from offset 0. */\n public async listPokemonShapes(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonShape>> {\n return this.getListResource<PokemonShape>(ENDPOINTS.POKEMON_SHAPE, offset, limit);\n }\n\n /** List Pokémon Species. Page defaults to 20 entries from offset 0. */\n public async listPokemonSpecies(\n offset?: number,\n limit?: number,\n ): Promise<NamedAPIResourceList<PokemonSpecies>> {\n return this.getListResource<PokemonSpecies>(ENDPOINTS.POKEMON_SPECIES, offset, limit);\n }\n\n /** List Stats. Page defaults to 20 entries from offset 0. */\n public async listStats(offset?: number, limit?: number): Promise<NamedAPIResourceList<Stat>> {\n return this.getListResource<Stat>(ENDPOINTS.STAT, offset, limit);\n }\n\n /** List Types. Page defaults to 20 entries from offset 0. */\n public async listTypes(offset?: number, limit?: number): Promise<NamedAPIResourceList<Type>> {\n return this.getListResource<Type>(ENDPOINTS.TYPE, offset, limit);\n }\n}\n","import { ENDPOINTS } from \"@constants\";\nimport type { Language, NamedAPIResourceList } from \"@models\";\nimport { BaseClient, type ResourceLink } from \"./base\";\n\n/**\n * ### Utility Client\n *\n * Client used to access the Utility Endpoints:\n *\n * - [Languages](https://pokeapi.co/docs/v2#languages)\n * - [Resources](https://pokeapi.co/docs/v2#resource-listspagination-section)\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2#utility-section)\n */\nexport class UtilityClient extends BaseClient {\n /** Get a Language by its ID. */\n public async getLanguageById(id: number): Promise<Language> {\n return this.getResource(ENDPOINTS.LANGUAGE, id);\n }\n\n /** Get a Language by its name. */\n public async getLanguageByName(name: string): Promise<Language> {\n return this.getResource(ENDPOINTS.LANGUAGE, name);\n }\n\n /**\n * Get any resource by its URL, or by a link taken from another response.\n *\n * ```ts\n * const pokemon = await api.pokemon.getPokemonByName('luxray');\n * const species = await api.utility.getResourceByUrl(pokemon.species);\n * // ^? PokemonSpecies\n * ```\n *\n * Every client carries {@link BaseClient.resolve}, which does the same thing;\n * this is the name it went out under, and it stays.\n *\n * @param resource The absolute URL of the resource, or a link to it.\n * @returns The resource the URL points at.\n * @throws {TypeError} If the URL is not valid, or names no PokéAPI endpoint.\n */\n public async getResourceByUrl<T>(resource: ResourceLink<T>): Promise<T> {\n return this.resolve<T>(resource);\n }\n\n /** List Languages. Page defaults to 20 entries from offset 0. */\n public listLanguages(offset?: number, limit?: number): Promise<NamedAPIResourceList<Language>> {\n return this.getListResource<Language>(ENDPOINTS.LANGUAGE, offset, limit);\n }\n}\n","import { Transport } from \"../internal/transport\";\nimport { ClientFacade, type ClientOptions } from \"./base\";\nimport { BerryClient } from \"./berry.client\";\nimport { ContestClient } from \"./contest.client\";\nimport { CurrencyClient } from \"./currency.client\";\nimport { EncounterClient } from \"./encounter.client\";\nimport { EvolutionClient } from \"./evolution.client\";\nimport { GameClient } from \"./game.client\";\nimport { ItemClient } from \"./item.client\";\nimport { LocationClient } from \"./location.client\";\nimport { MachineClient } from \"./machine.client\";\nimport { MoveClient } from \"./move.client\";\nimport { PokemonClient } from \"./pokemon.client\";\nimport { UtilityClient } from \"./utility.client\";\n\n/**\n * ### Main Client\n *\n * The main client used to access all the PokéAPI Endpoints:\n *\n * - [Berries](https://pokeapi.co/docs/v2#berries-section)\n * - [Contests](https://pokeapi.co/docs/v2#contests-section)\n * - [Currencies](https://pokeapi.co/docs/v2#currencies-section)\n * - [Encounters](https://pokeapi.co/docs/v2#encounters-section)\n * - [Evolution](https://pokeapi.co/docs/v2#evolution-section)\n * - [Games](https://pokeapi.co/docs/v2#games-section)\n * - [Items](https://pokeapi.co/docs/v2#items-section)\n * - [Locations](https://pokeapi.co/docs/v2#locations-section)\n * - [Machines](https://pokeapi.co/docs/v2#machines-section)\n * - [Moves](https://pokeapi.co/docs/v2#moves-section)\n * - [Pokémon](https://pokeapi.co/docs/v2#pokemon-section)\n * - [Utility](https://pokeapi.co/docs/v2#utility-section)\n *\n * All the clients below share a single transport, so a resource fetched through\n * one of them is served from cache by the rest — and two of them asking for the\n * same URL at once make one round trip, not two.\n *\n * Composes its sections rather than inheriting from them: it extends\n * {@link ClientFacade}, not {@link BaseClient}, so it carries no endpoint of its\n * own.\n *\n * See [PokéAPI Documentation](https://pokeapi.co/docs/v2)\n */\nexport class MainClient extends ClientFacade {\n public readonly berry: BerryClient;\n public readonly contest: ContestClient;\n public readonly currency: CurrencyClient;\n public readonly encounter: EncounterClient;\n public readonly evolution: EvolutionClient;\n public readonly game: GameClient;\n public readonly item: ItemClient;\n public readonly location: LocationClient;\n public readonly machine: MachineClient;\n public readonly move: MoveClient;\n public readonly pokemon: PokemonClient;\n public readonly utility: UtilityClient;\n\n constructor(options?: ClientOptions);\n /** @internal Shares the transport a client already holds. */\n constructor(source?: ClientOptions | Transport);\n constructor(source?: ClientOptions | Transport) {\n // Built here rather than read back off the facade, which keeps it private:\n // one transport handed to all twelve, so a cached response, a learned ETag\n // and a request already on the wire are each worth having in every section\n // rather than only in the one that paid for it.\n const transport = source instanceof Transport ? source : Transport.create(source);\n\n super(transport);\n\n this.berry = new BerryClient(transport);\n this.contest = new ContestClient(transport);\n this.currency = new CurrencyClient(transport);\n this.encounter = new EncounterClient(transport);\n this.evolution = new EvolutionClient(transport);\n this.game = new GameClient(transport);\n this.item = new ItemClient(transport);\n this.location = new LocationClient(transport);\n this.machine = new MachineClient(transport);\n this.move = new MoveClient(transport);\n this.pokemon = new PokemonClient(transport);\n this.utility = new UtilityClient(transport);\n }\n}\n","import type {\n ChainLink,\n EvolutionChain,\n EvolutionDetail,\n EvolutionTimeOfDay,\n EvolutionTrigger,\n EvolutionTriggerName,\n Item,\n Location,\n Move,\n NamedAPIResource,\n PokemonForm,\n PokemonSpecies,\n Region,\n Type,\n} from \"@models\";\n\n/**\n * ## Evolution Step\n * One edge of an evolution chain: a species, what it evolves into, and every way\n * that happens.\n */\nexport interface EvolutionStep {\n /** The species that evolves. */\n from: NamedAPIResource<PokemonSpecies>;\n /** What it evolves into. */\n to: NamedAPIResource<PokemonSpecies>;\n /**\n * The ways this step happens, which are alternatives rather than a sequence —\n * the API publishes one per version group, so Leafeon carries five mossy-rock\n * locations and a Leaf Stone. Never empty.\n */\n details: EvolutionDetail[];\n /** How deep in the chain this step sits: `1` for a first evolution. */\n depth: number;\n /** Whether {@link EvolutionStep.to} is a baby Pokémon. */\n isBaby: boolean;\n}\n\n/**\n * ## Flatten Options\n * How {@link flattenChain} narrows the chain it walks.\n */\nexport interface FlattenOptions {\n /**\n * Keep only the details tagged with this version group, by the name the API\n * gives it — `sword-shield`, not `Sword/Shield` — and drop the steps left with\n * none. The tag is the game that introduced the method, not every game it\n * applies in — see {@link flattenChain}.\n */\n versionGroup?: string;\n}\n\n/** The details of a link, narrowed to one version group when asked for. */\nconst detailsFor = (link: ChainLink, versionGroup: string | undefined): EvolutionDetail[] =>\n versionGroup === undefined\n ? link.evolution_details\n : link.evolution_details.filter((detail) => detail.version_group.name === versionGroup);\n\n/**\n * Flattens an evolution chain into one step per evolution, depth-first in the\n * order the API lists them.\n *\n * ```ts\n * const species = await api.pokemon.getPokemonSpeciesByName('eevee');\n * const chain = await api.resolve(species.evolution_chain);\n *\n * for (const step of flattenChain(chain)) {\n * console.log(`${step.from.name} → ${step.to.name}`);\n * }\n * ```\n *\n * The root is not a step: it is what the chain starts from, and the API gives it\n * no `evolution_details` to describe.\n *\n * `versionGroup` keeps only the details tagged with that version group, which is\n * what picks the Leaf Stone out of Leafeon's six alternatives:\n *\n * ```ts\n * flattenChain(chain, { versionGroup: 'sword-shield' });\n * ```\n *\n * That tag is the game which *introduced* the method, not every game it applies\n * in: Eevee's Water Stone is tagged `red-blue` alone, so filtering to\n * `sword-shield` drops Vaporeon even though Sword/Shield evolves it the same way\n * it always did. The question this answers is what a game changed.\n *\n * A step with nothing left after that is dropped, but the chain below it is\n * still walked — every edge is filtered on its own terms, and `depth` stays the\n * position in the chain rather than in the result.\n */\nexport const flattenChain = (chain: EvolutionChain, options?: FlattenOptions): EvolutionStep[] => {\n const collect = (link: ChainLink, depth: number): EvolutionStep[] =>\n link.evolves_to.flatMap((next) => {\n const details = detailsFor(next, options?.versionGroup);\n const below = collect(next, depth + 1);\n\n if (details.length === 0) {\n return below;\n }\n\n return [\n { from: link.species, to: next.species, details, depth, isBaby: next.is_baby },\n ...below,\n ];\n });\n\n return collect(chain.chain, 1);\n};\n\n/**\n * The steps leading from the root of a chain to `species`.\n *\n * ```ts\n * pathTo(chain, 'dustox')?.map((step) => step.to.name); // ['cascoon', 'dustox']\n * ```\n *\n * Matched against the name the API gives a species, which is not the name a game\n * displays: `localize(species.names)` is `Papilord` in French and finds nothing\n * here. Pass the link itself when you have one.\n *\n * @returns The steps, `[]` when `species` is the root the chain starts from, and\n * `undefined` when the chain does not contain it. The two empty answers are\n * different questions, so they are different values.\n */\nexport const pathTo = (\n chain: EvolutionChain,\n species: string | NamedAPIResource<PokemonSpecies>,\n): EvolutionStep[] | undefined => {\n const wanted = typeof species === \"string\" ? species : species.name;\n\n const search = (link: ChainLink, trail: EvolutionStep[]): EvolutionStep[] | undefined => {\n if (link.species.name === wanted) {\n return trail;\n }\n\n for (const next of link.evolves_to) {\n const step: EvolutionStep = {\n from: link.species,\n to: next.species,\n details: next.evolution_details,\n depth: trail.length + 1,\n isBaby: next.is_baby,\n };\n const found = search(next, [...trail, step]);\n\n if (found !== undefined) {\n return found;\n }\n }\n\n return undefined;\n };\n\n return search(chain.chain, []);\n};\n\n/**\n * ## Evolution Requirement\n * One condition an evolution is subject to, as a discriminated union — what an\n * {@link EvolutionDetail}'s thirty-odd nullable fields say, without the nulls.\n *\n * `is_default` and `version_group` are not here: they describe the record, not\n * what the Pokémon has to do.\n */\nexport type EvolutionRequirement =\n | { kind: \"trigger\"; trigger: NamedAPIResource<EvolutionTrigger> }\n | { kind: \"item\"; item: NamedAPIResource<Item> }\n | { kind: \"held-item\"; item: NamedAPIResource<Item> }\n | { kind: \"min-level\"; level: number }\n | { kind: \"min-happiness\"; happiness: number }\n | { kind: \"min-beauty\"; beauty: number }\n | { kind: \"min-affection\"; affection: number }\n | { kind: \"known-move\"; move: NamedAPIResource<Move> }\n | { kind: \"known-move-type\"; type: NamedAPIResource<Type> }\n | { kind: \"used-move\"; move: NamedAPIResource<Move> }\n | { kind: \"min-move-count\"; count: number }\n | { kind: \"min-steps\"; steps: number }\n | { kind: \"min-damage-taken\"; damage: number }\n | { kind: \"location\"; location: NamedAPIResource<Location> }\n | { kind: \"region\"; region: NamedAPIResource<Region> }\n | { kind: \"time-of-day\"; time: EvolutionTimeOfDay }\n | { kind: \"gender\"; gender: number }\n | { kind: \"relative-physical-stats\"; comparison: 1 | 0 | -1 }\n | { kind: \"party-species\"; species: NamedAPIResource<PokemonSpecies> }\n | { kind: \"party-type\"; type: NamedAPIResource<Type> }\n | { kind: \"trade-species\"; species: NamedAPIResource<PokemonSpecies> }\n | { kind: \"base-form\"; form: NamedAPIResource<PokemonForm> }\n | { kind: \"evolved-form\"; form: NamedAPIResource<PokemonForm> }\n | { kind: \"needs-overworld-rain\" }\n | { kind: \"turn-upside-down\" }\n | { kind: \"near-special-rock\" }\n | { kind: \"needs-multiplayer\" };\n\n/**\n * One reader per field an {@link EvolutionDetail} can set, in the order the\n * requirements come out, each `null` when its field is unset.\n */\nconst READERS: ((detail: EvolutionDetail) => EvolutionRequirement | null)[] = [\n ({ item }) => (item === null ? null : { kind: \"item\", item }),\n ({ held_item: item }) => (item === null ? null : { kind: \"held-item\", item }),\n ({ min_level: level }) => (level === null ? null : { kind: \"min-level\", level }),\n ({ min_happiness: happiness }) =>\n happiness === null ? null : { kind: \"min-happiness\", happiness },\n ({ min_beauty: beauty }) => (beauty === null ? null : { kind: \"min-beauty\", beauty }),\n ({ min_affection: affection }) =>\n affection === null ? null : { kind: \"min-affection\", affection },\n ({ known_move: move }) => (move === null ? null : { kind: \"known-move\", move }),\n ({ known_move_type: type }) => (type === null ? null : { kind: \"known-move-type\", type }),\n ({ used_move: move }) => (move === null ? null : { kind: \"used-move\", move }),\n ({ min_move_count: count }) => (count === null ? null : { kind: \"min-move-count\", count }),\n ({ min_steps: steps }) => (steps === null ? null : { kind: \"min-steps\", steps }),\n ({ min_damage_taken: damage }) => (damage === null ? null : { kind: \"min-damage-taken\", damage }),\n ({ location }) => (location === null ? null : { kind: \"location\", location }),\n ({ region }) => (region === null ? null : { kind: \"region\", region }),\n ({ time_of_day: time }) => (time === \"\" ? null : { kind: \"time-of-day\", time }),\n ({ gender }) => (gender === null ? null : { kind: \"gender\", gender }),\n ({ relative_physical_stats: comparison }) =>\n comparison === null ? null : { kind: \"relative-physical-stats\", comparison },\n ({ party_species: species }) => (species === null ? null : { kind: \"party-species\", species }),\n ({ party_type: type }) => (type === null ? null : { kind: \"party-type\", type }),\n ({ trade_species: species }) => (species === null ? null : { kind: \"trade-species\", species }),\n ({ base_form: form }) => (form === null ? null : { kind: \"base-form\", form }),\n ({ evolved_form: form }) => (form === null ? null : { kind: \"evolved-form\", form }),\n ({ needs_overworld_rain: rain }) => (rain ? { kind: \"needs-overworld-rain\" } : null),\n ({ turn_upside_down: upsideDown }) => (upsideDown ? { kind: \"turn-upside-down\" } : null),\n ({ near_special_rock: rock }) => (rock ? { kind: \"near-special-rock\" } : null),\n ({ needs_multiplayer: multiplayer }) => (multiplayer ? { kind: \"needs-multiplayer\" } : null),\n];\n\n/**\n * The conditions one {@link EvolutionDetail} sets out, with everything it left\n * unset dropped.\n *\n * ```ts\n * requirementsOf(step.details[0]); // eevee → umbreon\n * // [\n * // { kind: 'trigger', trigger: { name: 'level-up', … } },\n * // { kind: 'min-happiness', happiness: 160 },\n * // { kind: 'time-of-day', time: 'night' },\n * // { kind: 'base-form', form: { name: 'eevee', … } },\n * // ]\n * ```\n *\n * The trigger leads, so rendering the result is a walk over one array.\n *\n * Every field is tested against the value the API uses for \"unset\" rather than\n * for truthiness: `relative_physical_stats` is `0` when Attack has to equal\n * Defense, and `time_of_day` is `''`.\n */\nexport const requirementsOf = (detail: EvolutionDetail): EvolutionRequirement[] => [\n { kind: \"trigger\", trigger: detail.trigger },\n ...READERS.flatMap((read) => read(detail) ?? []),\n];\n\n/**\n * Every trigger as a verb phrase. Exhaustive over {@link EvolutionTriggerName},\n * so a trigger added to that union has to be given words here too.\n */\nconst TRIGGERS: Record<EvolutionTriggerName, string> = {\n \"level-up\": \"level up\",\n trade: \"trade\",\n \"use-item\": \"use an item\",\n shed: \"shed\",\n spin: \"spin\",\n \"tower-of-darkness\": \"train in the Tower of Darkness\",\n \"tower-of-waters\": \"train in the Tower of Waters\",\n \"three-critical-hits\": \"land three critical hits in one battle\",\n \"take-damage\": \"take damage\",\n other: \"an in-game event\",\n \"agile-style-move\": \"use agile style moves\",\n \"strong-style-move\": \"use strong style moves\",\n \"recoil-damage\": \"take recoil damage\",\n \"use-move\": \"use a move\",\n \"three-defeated-bisharp\": \"defeat three pack-leading Bisharp\",\n \"gimmighoul-coins\": \"collect Gimmighoul Coins\",\n};\n\n/** A resource name as prose: the API writes them kebab-cased and lower case. */\nconst spaced = (resource: NamedAPIResource<unknown>): string => resource.name.replaceAll(\"-\", \" \");\n\n/**\n * Every time of day as a phrase. Exhaustive over {@link EvolutionTimeOfDay}, so\n * a value added to that union has to be given words here too — `dusk` and\n * `full-moon` do not fit the \"during the …\" the other two take.\n */\nconst TIMES: Record<EvolutionTimeOfDay, string> = {\n day: \"during the day\",\n night: \"during the night\",\n dusk: \"at dusk\",\n \"full-moon\": \"under a full moon\",\n};\n\nconst GENDERS: Record<number, string> = { 1: \"female\", 2: \"male\", 3: \"genderless\" };\n\n/** Unknown ids name themselves, so a gender added upstream still renders. */\nconst genderName = (gender: number): string => GENDERS[gender] ?? `gender ${gender}`;\n\nconst COMPARISONS: Record<string, string> = { \"1\": \">\", \"0\": \"=\", \"-1\": \"<\" };\n\n/**\n * ## Requirement Phrases\n * One renderer per {@link EvolutionRequirement} kind. Exhaustive, so a kind added\n * to that union has to be given words here too.\n */\nexport type RequirementPhrases = {\n [K in EvolutionRequirement[\"kind\"]]: (\n requirement: Extract<EvolutionRequirement, { kind: K }>,\n ) => string;\n};\n\n/**\n * ## Resource Namer\n * How a resource a requirement names is written out.\n *\n * @param resource The item, move, species, location, region, form or type the\n * requirement carries.\n * @returns What to print for it.\n */\nexport type ResourceNamer = (resource: NamedAPIResource<unknown>) => string;\n\n/**\n * Builds the English table around a way of naming resources.\n *\n * Everything except the name is fixed; `namer` is the one thing a caller who\n * keeps the English sentence still has to replace, because `spaced` prints what\n * the API calls a resource and no localized name is derivable from it.\n *\n * ```ts\n * const names = new Map([['water-stone', 'Pedra da Água']]);\n *\n * requirementPhrases((resource) => names.get(resource.name) ?? resource.name);\n * ```\n *\n * @param namer How to write a resource out. Defaults to the API's own name, with\n * the hyphens turned to spaces.\n */\nexport const requirementPhrases = (namer: ResourceNamer = spaced): RequirementPhrases => ({\n trigger: ({ trigger }) => TRIGGERS[trigger.name as EvolutionTriggerName] ?? namer(trigger),\n item: ({ item }) => `use ${namer(item)}`,\n \"held-item\": ({ item }) => `holding ${namer(item)}`,\n \"min-level\": ({ level }) => `at level ${level}`,\n \"min-happiness\": ({ happiness }) => `with at least ${happiness} happiness`,\n \"min-beauty\": ({ beauty }) => `with at least ${beauty} beauty`,\n \"min-affection\": ({ affection }) => `with at least ${affection} affection`,\n \"known-move\": ({ move }) => `knowing ${namer(move)}`,\n \"known-move-type\": ({ type }) => `knowing a ${namer(type)}-type move`,\n \"used-move\": ({ move }) => `after using ${namer(move)}`,\n \"min-move-count\": ({ count }) => `${count} times`,\n \"min-steps\": ({ steps }) => `after ${steps} steps`,\n \"min-damage-taken\": ({ damage }) => `after taking ${damage} damage`,\n location: ({ location }) => `at ${namer(location)}`,\n region: ({ region }) => `in ${namer(region)}`,\n \"time-of-day\": ({ time }) => TIMES[time],\n gender: ({ gender }) => `as a ${genderName(gender)}`,\n \"relative-physical-stats\": ({ comparison }) =>\n `with Attack ${COMPARISONS[String(comparison)]} Defense`,\n \"party-species\": ({ species }) => `with ${namer(species)} in the party`,\n \"party-type\": ({ type }) => `with a ${namer(type)}-type in the party`,\n \"trade-species\": ({ species }) => `traded for ${namer(species)}`,\n \"base-form\": ({ form }) => `in its ${namer(form)} form`,\n \"evolved-form\": ({ form }) => `into its ${namer(form)} form`,\n \"needs-overworld-rain\": () => \"while it is raining\",\n \"turn-upside-down\": () => \"with the console upside down\",\n \"near-special-rock\": () => \"near a special rock\",\n \"needs-multiplayer\": () => \"in multiplayer\",\n});\n\n/**\n * ## Requirement Phrases\n * The English {@link formatRequirements} renders with, naming resources the way\n * the API does. Exported so a caller can replace the wording of one kind — or\n * all of them, in another language — without rebuilding the rest of the renderer\n * around it, and so an override can fall back to the default for what it does\n * not handle.\n *\n * ```ts\n * formatRequirements(requirements, {\n * phrases: { 'min-happiness': ({ happiness }) => `com ${happiness} de felicidade` },\n * });\n *\n * formatRequirements(requirements, {\n * phrases: {\n * trigger: (requirement) => MINE[requirement.trigger.name] ?? REQUIREMENT_PHRASES.trigger(requirement),\n * },\n * });\n * ```\n */\nexport const REQUIREMENT_PHRASES: RequirementPhrases = requirementPhrases();\n\n/**\n * The table built for a namer, kept so that rendering a list does not rebuild\n * twenty-seven closures per row. Weak, so a namer closed over a component's\n * props is not held alive by having been used once.\n */\nconst tables = new WeakMap<ResourceNamer, RequirementPhrases>();\n\nconst tableFor = (namer: ResourceNamer | undefined): RequirementPhrases => {\n if (namer === undefined) {\n return REQUIREMENT_PHRASES;\n }\n\n const built = tables.get(namer) ?? requirementPhrases(namer);\n tables.set(namer, built);\n\n return built;\n};\n\n/**\n * The table is keyed by `kind` and the union is discriminated by it, so the two\n * are known to line up — but only one entry at a time, which is not something an\n * index of the whole table can be written to say.\n */\nconst phrase = (requirement: EvolutionRequirement, phrases: RequirementPhrases): string =>\n (phrases[requirement.kind] as (value: EvolutionRequirement) => string)(requirement);\n\n/**\n * ## Format Options\n * How {@link formatRequirements} words what it renders.\n */\nexport interface FormatOptions {\n /**\n * How to write out the resources the requirements name. Defaults to the API's\n * own name with the hyphens turned to spaces — `water stone`.\n *\n * This is the half of a translation that `phrases` cannot do: a display name\n * is `localize(item.names)`, which is a request, so it has to come from the\n * caller. Applied to the default table, and to nothing a `phrases` entry\n * overrides — that entry is handed the resource and names it however it likes.\n *\n * Hold the function rather than writing it inline: the table built around a\n * namer is kept and reused, and a new closure per call is a new table per call.\n */\n name?: ResourceNamer;\n /**\n * Wording for the kinds named, {@link REQUIREMENT_PHRASES} for the rest —\n * everything around it, including the `use-item` de-duplication, stays.\n */\n phrases?: Partial<RequirementPhrases>;\n}\n\n/**\n * Renders requirements as an English phrase.\n *\n * ```ts\n * formatRequirements(requirementsOf(detail)); // eevee → umbreon\n * // 'level up, with at least 160 happiness, during the night, in its eevee form'\n * ```\n *\n * The only English in the library, and a separate export for that reason: an\n * application rendering its own copy — in its own language, or as anything other\n * than a sentence — drops this and the phrase table with it. Use\n * {@link requirementsOf} for that, or `phrases` to keep the sentence and change\n * the words:\n *\n * ```ts\n * formatRequirements(requirements, { phrases: { trade: () => 'by trade' } });\n * ```\n *\n * Resources are named the way the API names them, not the way a game displays\n * them. `localize(item.names)` is the display name, it costs a request, and\n * `name` is where it goes:\n *\n * ```ts\n * const items = await api.resolveAll(links);\n * const display = new Map(items.map((item) => [item.name, localize(item.names)?.name]));\n *\n * formatRequirements(requirements, { name: (resource) => display.get(resource.name) ?? resource.name });\n * // 'use Water Stone'\n * ```\n *\n * The two options are the two halves of a translation and are independent:\n * `phrases` is the words the library supplies, `name` the words the API does.\n *\n * A `use-item` trigger and the item it uses are one phrase, since \"use an item,\n * use water stone\" says it twice. That holds under `phrases` too: the trigger is\n * dropped before anything is rendered, so an overridden `item` is still what says\n * the item is used.\n */\nexport const formatRequirements = (\n requirements: readonly EvolutionRequirement[],\n options?: FormatOptions,\n): string => {\n const phrases = { ...tableFor(options?.name), ...options?.phrases };\n\n const usesItem =\n requirements.some((requirement) => requirement.kind === \"item\") &&\n requirements.some(\n (requirement) => requirement.kind === \"trigger\" && requirement.trigger.name === \"use-item\",\n );\n\n return requirements\n .filter((requirement) => !(usesItem && requirement.kind === \"trigger\"))\n .map((requirement) => phrase(requirement, phrases))\n .join(\", \");\n};\n","import type { Language, NamedAPIResource } from \"@models\";\n\n/**\n * ## Localized\n * An entry the PokéAPI publishes once per language — a `Name`, `FlavorText`,\n * `Description`, `Effect`, `VerboseEffect`, and everything shaped like them.\n */\nexport interface Localized {\n language: NamedAPIResource<Language>;\n}\n\n/**\n * ## Localize Options\n * Which language to pick, and which to settle for.\n */\nexport interface LocalizeOptions {\n /** The language wanted, by the name the PokéAPI gives it. Defaults to `en`. */\n language?: string;\n /**\n * The language to try when the first one is absent. Left out, nothing is tried\n * and the answer is `undefined` — a fallback is a decision about the product,\n * not a default.\n */\n fallback?: string;\n}\n\nconst optionsOf = (\n language: string | LocalizeOptions | undefined,\n): LocalizeOptions & { language: string } => {\n const options = typeof language === \"string\" ? { language } : (language ?? {});\n\n return { ...options, language: options.language ?? \"en\" };\n};\n\n/** Every entry written in one language, matched without regard to case. */\nconst inLanguage = <T extends Localized>(entries: readonly T[], language: string): T[] => {\n const wanted = language.toLowerCase();\n\n return entries.filter((entry) => entry.language.name.toLowerCase() === wanted);\n};\n\n/**\n * Picks the entry written in `language`, by the name the PokéAPI gives that\n * language: `en`, `ja`, `ja-hrkt`, `zh-hans`, `es-419`, and so on.\n *\n * ```ts\n * const species = await api.pokemon.getPokemonSpeciesByName('eevee');\n *\n * localize(species.names)?.name; // 'Eevee'\n * localize(species.names, 'ja')?.name; // 'イーブイ'\n * localize(species.names, { language: 'gd', fallback: 'en' })?.name; // 'Eevee'\n * ```\n *\n * Matched without regard to case: the PokéAPI writes these tags in lower case,\n * while BCP 47 capitalizes the script subtag — `ja-Hrkt` is the form anyone used\n * to language tags will reach for, and it should not silently match nothing.\n *\n * A section may list several entries for one language — flavor text, one per\n * version — and the first is the one returned. {@link localizeAll} is the way to\n * see the rest and pick by version.\n *\n * @returns The entry, the one in `fallback` when that language is absent, or\n * `undefined` when neither is there.\n */\nexport const localize = <T extends Localized>(\n entries: readonly T[],\n language?: string | LocalizeOptions,\n): T | undefined => localizeAll(entries, language)[0];\n\n/**\n * Every entry written in `language`, in the order the API lists them.\n *\n * ```ts\n * const species = await api.pokemon.getPokemonSpeciesByName('eevee');\n *\n * const entries = localizeAll(species.flavor_text_entries, 'en');\n * entries.find((entry) => entry.version.name === 'sword')?.flavor_text;\n * ```\n *\n * Which is what a section publishing one entry per version needs: `localize`\n * answers with the first, and the first is an arbitrary game's Pokédex entry\n * rather than the one asked for. The version is on the entry — `version` on\n * flavor text, `version_group` on the sections that change per group — so the\n * filter belongs to the caller, who knows which of the two is there.\n *\n * @returns The entries, those in `fallback` when the language is absent, or `[]`\n * when neither is there.\n */\nexport const localizeAll = <T extends Localized>(\n entries: readonly T[],\n language?: string | LocalizeOptions,\n): T[] => {\n const options = optionsOf(language);\n const matched = inLanguage(entries, options.language);\n\n if (matched.length > 0 || options.fallback === undefined) {\n return matched;\n }\n\n return inLanguage(entries, options.fallback);\n};\n","// Relative rather than through `@clients`, which does not export `base.ts`.\nimport type { ResourceLink } from \"../clients/base\";\n\n/**\n * The trailing id of a PokéAPI resource URL, with or without the final slash.\n *\n * Signed: `move-ailment/-1` is the \"unknown\" ailment, and it is a resource the\n * API lists and serves like any other.\n */\nconst TRAILING_ID = /\\/(-?\\d+)\\/?$/;\n\n/**\n * The id inside a resource URL, without a request.\n *\n * ```ts\n * const page = await api.pokemon.listPokemons(0, 20);\n *\n * page.results.map((link) => getPokemonSpriteUrl(resourceId(link)));\n * ```\n *\n * A list page gives names and URLs and no ids, while the sprite repository is\n * keyed by id alone — this is what joins the two, and it is what lets a grid of\n * every Pokémon render off one list request instead of one request per card.\n *\n * The id is read off the URL rather than fetched, so it is only as good as the\n * link: a URL the API did not write is not promised to end in one.\n *\n * @param resource The link, as a URL or as the resource object carrying one.\n * @returns The id.\n * @throws {TypeError} If the URL does not end in an id.\n */\nexport const resourceId = (resource: ResourceLink<unknown>): number => {\n const url = typeof resource === \"string\" ? resource : resource.url;\n const match = TRAILING_ID.exec(url);\n\n if (match === null) {\n throw new TypeError(`No resource id in URL: ${url}`);\n }\n\n return Number(match[1]);\n};\n","import { BASE_URL } from \"@constants\";\n\n/**\n * ## Sprite Variant\n * The sprite sets the PokéAPI publishes for a Pokémon.\n */\nexport type SpriteVariant = \"default\" | \"official-artwork\" | \"home\" | \"dream-world\" | \"showdown\";\n\n/**\n * ## Pokemon Sprite Options\n * Which sprite to build a URL for.\n *\n * The sets do not carry the same images, so the options are constrained per\n * variant: only `default` and `showdown` have back-facing sprites, and only\n * `official-artwork` has no gendered ones.\n */\nexport type PokemonSpriteOptions =\n | { variant?: \"default\"; shiny?: boolean; back?: boolean; female?: boolean }\n | { variant: \"showdown\"; shiny?: boolean; back?: boolean; female?: boolean }\n | { variant: \"home\"; shiny?: boolean; female?: boolean; back?: never }\n | { variant: \"official-artwork\"; shiny?: boolean; back?: never; female?: never }\n | { variant: \"dream-world\"; female?: boolean; shiny?: never; back?: never };\n\ninterface VariantSpec {\n /** Path under `sprites/pokemon`. Empty for the default set, which sits at the root. */\n directory: string;\n extension: string;\n}\n\nconst VARIANTS: Record<SpriteVariant, VariantSpec> = {\n default: { directory: \"\", extension: \"png\" },\n \"official-artwork\": { directory: \"other/official-artwork\", extension: \"png\" },\n home: { directory: \"other/home\", extension: \"png\" },\n \"dream-world\": { directory: \"other/dream-world\", extension: \"svg\" },\n showdown: { directory: \"other/showdown\", extension: \"gif\" },\n};\n\n/**\n * Builds the URL of a Pokémon sprite, without a request.\n *\n * ```ts\n * getPokemonSpriteUrl(25); // front, default set\n * getPokemonSpriteUrl(25, { variant: \"official-artwork\" });\n * getPokemonSpriteUrl(25, { variant: \"showdown\", back: true, shiny: true });\n * ```\n *\n * The sprite repository does not hold every combination for every Pokémon — a\n * back-facing sprite of a recent generation, or a gendered form of a species with\n * one appearance, simply does not exist. This builds a well-formed URL; it does\n * not promise the file is there.\n *\n * @param id The Pokémon ID. Names are not addressable — the sprites are keyed by ID.\n * @param options Which sprite set and which facing to build for.\n * @returns The URL of the sprite.\n */\nexport const getPokemonSpriteUrl = (id: number, options: PokemonSpriteOptions = {}): string => {\n const { variant = \"default\", shiny = false, back = false, female = false } = options;\n const { directory, extension } = VARIANTS[variant];\n\n // The repository nests the modifiers in this order, so `back/shiny/female` is\n // the only path that resolves.\n const segments = [directory, back && \"back\", shiny && \"shiny\", female && \"female\"];\n\n return [BASE_URL.SPRITES, \"pokemon\", ...segments.filter(Boolean), `${id}.${extension}`].join(\"/\");\n};\n","import { GENERATIONS, type GenerationName, TYPES, type TypeName } from \"@constants\";\nimport type { NamedAPIResource, Type, TypeRelations } from \"@models\";\n\n/**\n * The names {@link TypeName} declares, at runtime. Read off {@link TYPES} by id\n * rather than written out a second time: `unknown` and `shadow` are the ids above\n * 10000, the way every other section marks what is not part of the main games.\n *\n * `constants.live.spec.ts` is what holds the two to the same set — the ids are\n * upstream's, and a type arriving above 10000 that does belong in a matchup would\n * pass here unnoticed.\n */\nconst TYPE_NAMES: ReadonlySet<string> = new Set(\n Object.entries(TYPES)\n .filter(([, id]) => id < 10_000)\n .map(([key]) => key.toLowerCase()),\n);\n\nconst isTypeName = (name: string): name is TypeName => TYPE_NAMES.has(name);\n\n/** A generation {@link GENERATIONS} does not know, which is one this build predates. */\nconst UNKNOWN = -1;\n\n/**\n * The id {@link GENERATIONS} gives a generation, or {@link UNKNOWN} for a name\n * that is not one. Generations are compared by this rather than by name, which\n * does not sort.\n */\nconst rank = (name: string): number => {\n const key = name.toUpperCase().replaceAll(\"-\", \"_\") as keyof typeof GENERATIONS;\n\n return GENERATIONS[key] ?? UNKNOWN;\n};\n\n/** The offensive arrays of a {@link TypeRelations}, and what each one means. */\nconst MULTIPLIERS: readonly (readonly [keyof TypeRelations, number])[] = [\n [\"no_damage_to\", 0],\n [\"half_damage_to\", 0.5],\n [\"double_damage_to\", 2],\n];\n\n/** The defensive arrays, which say the same thing from the other side. */\nconst INCOMING: readonly (readonly [keyof TypeRelations, number])[] = [\n [\"no_damage_from\", 0],\n [\"half_damage_from\", 0.5],\n [\"double_damage_from\", 2],\n];\n\n/** Looks one type up in a set of arrays. Unlisted is neutral. */\nconst lookup = (\n relations: TypeRelations,\n arrays: readonly (readonly [keyof TypeRelations, number])[],\n name: string,\n): number => {\n for (const [key, multiplier] of arrays) {\n if (relations[key].some((type) => type.name === name)) {\n return multiplier;\n }\n }\n\n return 1;\n};\n\n/** What one attacking type does to one defending type. */\nconst against = (relations: TypeRelations, defending: string): number =>\n lookup(relations, MULTIPLIERS, defending);\n\n/** The multiplier a set of relations produces against every defending type. */\nconst multiply = (relations: TypeRelations, defending: readonly NamedAPIResource<Type>[]): number =>\n defending.reduce((total, type) => total * against(relations, type.name), 1);\n\n/**\n * ## Generation Scope\n * Which generation's type chart to read. Leave it out for the current one.\n */\nexport interface GenerationScope {\n generation?: GenerationName;\n}\n\n/**\n * The damage relations `type` had in `generation`, or the current ones when no\n * generation is named.\n *\n * ```ts\n * const ghost = await api.pokemon.getTypeByName('ghost');\n *\n * relationsFor(ghost).half_damage_to; // [dark]\n * relationsFor(ghost, 'generation-iii')?.half_damage_to; // [dark, steel]\n * ```\n *\n * Each entry in `past_damage_relations` records the *last* generation it applied\n * to, so the chart in force is the first entry still at or after the generation\n * asked for — Ghost's `generation-v` entry is what Ghost looked like from II\n * through V, and the current relations take over at VI.\n *\n * @returns The relations, or `undefined` when `type` did not exist yet in\n * `generation`. Nothing is guessed: Steel in generation I has no chart, and a\n * neutral one would be a confidently wrong answer rather than a missing one.\n */\nexport const relationsFor = (\n type: Type,\n generation?: GenerationName,\n): TypeRelations | undefined => {\n if (generation === undefined) {\n return type.damage_relations;\n }\n\n const wanted = rank(generation);\n\n // A generation this build has never heard of is a later one than it knows, so\n // the current chart is the best answer available. Ranking it -1 instead would\n // put it before every type's debut and report that nothing existed yet, which\n // is the same wrong answer the check below exists to avoid.\n if (wanted === UNKNOWN) {\n return type.damage_relations;\n }\n\n // Checked before the entries are: Steel's only past entry is `generation-v`,\n // which would otherwise answer for generation I, where Steel did not exist.\n if (wanted < rank(type.generation.name)) {\n return undefined;\n }\n\n // Sorted rather than trusted: the rule below is \"the first entry still at or\n // after\", and first means nothing in an order upstream never promised.\n const past = [...type.past_damage_relations]\n .sort((left, right) => rank(left.generation.name) - rank(right.generation.name))\n .find((entry) => rank(entry.generation.name) >= wanted);\n\n return past?.damage_relations ?? type.damage_relations;\n};\n\n/**\n * The damage multiplier `attacking` deals to a defender that has `defending`\n * types — `0`, `0.25`, `0.5`, `1`, `2` or `4`.\n *\n * ```ts\n * const fire = await api.pokemon.getTypeByName('fire');\n * const ferrothorn = await api.pokemon.getPokemonByName('ferrothorn');\n *\n * effectiveness(fire, ferrothorn.types.map((slot) => slot.type)); // 4\n * ```\n *\n * Read from the attacking type's own offensive relations, so this needs the one\n * type fetched rather than one per defending type.\n *\n * With a `generation`, the chart of that generation is used and the result is\n * `undefined` when `attacking` postdates it. Only the attacker is checked that\n * way: the defenders arrive as links, which carry no generation to check\n * against. `Pokemon.past_types` is where a historically correct defender comes\n * from.\n */\nexport function effectiveness(\n attacking: Type,\n defending: readonly NamedAPIResource<Type>[],\n): number;\nexport function effectiveness(\n attacking: Type,\n defending: readonly NamedAPIResource<Type>[],\n options: { generation: GenerationName },\n): number | undefined;\nexport function effectiveness(\n attacking: Type,\n defending: readonly NamedAPIResource<Type>[],\n options?: GenerationScope,\n): number | undefined {\n const relations = relationsFor(attacking, options?.generation);\n\n return relations === undefined ? undefined : multiply(relations, defending);\n}\n\n/**\n * What every one of `types` does to a defender that has `defending` types, keyed\n * by attacking type name — the \"what is this Pokémon weak to\" table.\n *\n * ```ts\n * const types: Type[] = [];\n * for await (const type of api.pokemon.paginate('listTypes', { resolve: true })) {\n * types.push(type);\n * }\n *\n * const profile = defensiveProfile(types, gengar.types.map((slot) => slot.type));\n * profile.psychic; // 2\n * profile.normal; // 0\n * ```\n *\n * The whole `type` section is one cached walk, and every lookup after that is\n * local. A type that did not exist in the generation asked for is left out of the\n * table rather than reported as neutral.\n *\n * `Partial` because of that, and because `types` is whatever the caller resolved:\n * an entry is there when the attacking type is, so every lookup is `number |\n * undefined`. `unknown` and `shadow` are not {@link TypeName}s and are skipped —\n * they hold no damage relations, so they have no place in a matchup table.\n *\n * Reach for {@link defensiveProfileFrom} unless you are asking about a past\n * generation: it answers the same question from the defender's own types, which\n * is one or two resources rather than the whole section. This is the form that\n * takes a `generation`, because only the attacking type carries the history.\n *\n * Keyed by the name the API gives a type, which is not the name a game displays:\n * `localize(type.names)` is what a table headed in French needs, and it is a\n * property of the resource rather than of this table.\n */\nexport const defensiveProfile = (\n types: readonly Type[],\n defending: readonly NamedAPIResource<Type>[],\n options?: GenerationScope,\n): Partial<Record<TypeName, number>> => {\n const profile: Partial<Record<TypeName, number>> = {};\n\n for (const attacking of types) {\n if (!isTypeName(attacking.name)) {\n continue;\n }\n\n const relations = relationsFor(attacking, options?.generation);\n\n if (relations !== undefined) {\n profile[attacking.name] = multiply(relations, defending);\n }\n }\n\n return profile;\n};\n\n/**\n * The same table, read off the defending types themselves — what every type does\n * to a Pokémon that has `defending` types.\n *\n * ```ts\n * const gengar = await api.pokemon.getPokemonByName('gengar');\n * const types = await api.resolveAll(gengar.types.map((slot) => slot.type));\n *\n * const profile = defensiveProfileFrom(types);\n * profile.psychic; // 2\n * profile.normal; // 0\n * ```\n *\n * Two requests for a dual-typed Pokémon, against the whole `type` section that\n * {@link defensiveProfile} needs — the answer is the same because the chart is\n * symmetric, which `tests/live/relations.live.spec.ts` is what keeps honest.\n *\n * Every {@link TypeName} is present: the defending types name every attacker\n * they interact with, and the rest are neutral rather than unknown. There is no\n * `generation` option for exactly the reason the entries are total — a defending\n * type's arrays are the current chart, and they have no way to say that an\n * attacking type did not exist yet. That question needs {@link defensiveProfile}.\n *\n * Keyed by the API's name for a type, as {@link defensiveProfile} is;\n * `localize(type.names)` is the displayed one.\n */\nexport const defensiveProfileFrom = (defending: readonly Type[]): Record<TypeName, number> => {\n // Total rather than `Partial`, and asserted because the loop is what makes it\n // so: `TYPE_NAMES` is {@link TypeName}'s own runtime image, and\n // `constants.live.spec.ts` is what holds the two to the same set.\n const profile = {} as Record<TypeName, number>;\n\n for (const name of TYPE_NAMES) {\n profile[name as TypeName] = defending.reduce(\n (total, type) => total * lookup(type.damage_relations, INCOMING, name),\n 1,\n );\n }\n\n return profile;\n};\n"],"mappings":"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"}