Full Code of PokeAPI/pokedex-promise-v2 for AI

master 39a288c8f403 cached
38 files
491.6 KB
113.8k tokens
382 symbols
1 requests
Download .txt
Showing preview only (510K chars total). Download the full file or copy to clipboard to get everything.
Repository: PokeAPI/pokedex-promise-v2
Branch: master
Commit: 39a288c8f403
Files: 38
Total size: 491.6 KB

Directory structure:
gitextract__53gir3x/

├── .editorconfig
├── .github/
│   └── workflows/
│       └── test.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── LICENSE
├── README.md
├── dist/
│   └── src/
│       ├── index.js
│       ├── interfaces/
│       │   └── PokeAPIOptions.js
│       └── utils/
│           ├── Endpoints.js
│           ├── ErrorHandler.js
│           ├── Getter.js
│           └── RootEndpoints.js
├── eslint.config.js
├── generator/
│   ├── .eslintrc
│   ├── AddJSDocs.ts
│   ├── Main.ts
│   ├── TypesGenerator.ts
│   ├── Utils.ts
│   └── tsconfig.json
├── package.json
├── src/
│   ├── index.ts
│   ├── interfaces/
│   │   ├── ListEndpointOptions.d.ts
│   │   └── PokeAPIOptions.ts
│   └── utils/
│       ├── Endpoints.ts
│       ├── ErrorHandler.ts
│       ├── Getter.ts
│       └── RootEndpoints.ts
├── test/
│   ├── .eslintrc
│   ├── Async.spec.ts
│   ├── Base.spec.ts
│   ├── ClearCache.spec.ts
│   ├── CommonCalls.spec.ts
│   ├── CustomUncommonCalls.spec.ts
│   ├── Resource.spec.ts
│   └── RootEndpoints.spec.ts
├── tsconfig.json
└── types/
    └── index.d.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100


================================================
FILE: .github/workflows/test.yml
================================================
name: Tests

on: [push, pull_request]

jobs:
  pnpm:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: ['18', '20']
    steps:
      - name: Clone repository
        uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'pnpm'
      - name: Install dependencies
        run: pnpm install
      - name: Setup pokeapi/api-data
        run: |
          pnpm run apidata:clone
          pnpm run apidata:replace
      - name: Build
        run: |
          pnpm run generate:types
          pnpm run generate:main
          pnpm run generate:jsdocs
      - name: Unit test
        run: |
          pnpm t
  npm:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: ['18', '20']
    steps:
      - name: Clone repository
        uses: actions/checkout@v4
      - name: Setup node
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install dependencies
        run: npm ci
      - name: Setup pokeapi/api-data
        run: |
          npm run apidata:clone
          npm run apidata:replace
      - name: Build
        run: |
          npm run generate:types
          npm run generate:main
          npm run generate:jsdocs
      - name: Unit test
        run: |
          npm t

  bun:
    runs-on: ubuntu-latest
    steps:
      - name: Clone repository
        uses: actions/checkout@v4
      - name: Setup bun
        uses: oven-sh/setup-bun@v2
      - name: Install dependencies
        run: bun install --frozen-lockfile
      - name: Setup pokeapi/api-data
        run: |
          bun run apidata:clone
          bun run apidata:replace
      - name: Build
        run: |
          bun run generate:types
          bun run generate:main
          bun run generate:jsdocs
      - name: Unit test
        run: |
          bun run test

  lint:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: ['lts/*']
    steps:
      - name: Clone repository
        uses: actions/checkout@v4
      - name: Setup node
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - name: Install dependencies
        run: npm ci
      - name: Lint
        run: |
          npm run lint


================================================
FILE: .gitignore
================================================
node_modules/
dist/generator/
dist/test/
api-data/

================================================
FILE: .npmignore
================================================
node_modules
test
.travis.yml
webpack.config.js
generator
dist/generator

================================================
FILE: .npmrc
================================================
legacy-peer-deps=true


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2016 Thomas Asadurian

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# pokedex-promise-v2 <a href="https://pokeapi.co/api/v2/pokemon/bulbasaur"><img src='https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/dream-world/1.svg' height=50px/></a>

[![npm version](https://badge.fury.io/js/pokedex-promise-v2.svg)](https://badge.fury.io/js/pokedex-promise-v2)
[![Tests](https://github.com/PokeAPI/pokedex-promise-v2/actions/workflows/test.yml/badge.svg)](https://github.com/PokeAPI/pokedex-promise-v2/actions/workflows/test.yml)
[![Package Quality](http://npm.packagequality.com/shield/pokedex-promise-v2.svg)](http://packagequality.com/#?package=pokedex-promise-v2)
[![npm](https://img.shields.io/npm/l/express.svg?maxAge=2592000)](https://github.com/PokeAPI/pokedex-promise-v2/blob/master/LICENSE)

Maintainers: [Naramsim](https://github.com/Naramsim), [TheTommyTwitch](https://github.com/TheTommyTwitch) and [HRKings](https://github.com/HRKings)

An easy way to use [Pokéapi](https://pokeapi.co/) v2 with promises *(or callbacks as of v3)* in node.js

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents**

- [pokedex-promise-v2](#pokedex-promise-v2-)
  - [Install](#install-)
  - [Usage](#usage)
    - [Example requests](#example-requests)
  - [Configuration](#configuration)
  - [Endpoints](#endpoints)
    - [Berries](#berries)
    - [Contests](#contests)
    - [Encounters](#encounters)
    - [Evolution](#evolution)
    - [Games](#games)
    - [Items](#items)
    - [Machines](#machines)
    - [Moves](#moves)
    - [Locations](#locations)
    - [Pokemon](#pokemon)
    - [Utility](#utility)
    - [Custom URLs and paths](#custom-urls-and-paths)
  - [Root Endpoints](#root-endpoints)
    - [List of supported root endpoints](#list-of-supported-root-endpoints)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Install [![nodeVersion](https://img.shields.io/badge/node->=12-brightgreen.svg)](https://www.npmjs.com/package/pokedex-promise-v2)

> As of 4.0.0 this package is now pure ESM. Please [read this](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c).

```sh
npm install pokedex-promise-v2 --save
```

```sh
yarn add pokedex-promise-v2
```

```sh
pnpm i pokedex-promise-v2
```

## Usage

```js
import Pokedex from 'pokedex-promise-v2';
const P = new Pokedex();
```

**NOTE**: Any function with the designation "ByName" can also be passed an integer ID. However, the functions with the designation "ById" can only be passed an integer ID. Refer to the [pokeapi v2 docs](http://pokeapi.co/docsv2/) to find out more about how the data is structured.

**UPDATE**: You can pass an array to each endpoint, it will retrive data for each array element. If you scroll down, you will find an example.

### Example requests

```js
(async () => { // with Async/Await
    try {
        const golduckSpecies = await P.getPokemonSpeciesByName("golduck")
        const frenchName = golduckSpecies.names.filter(pokeAPIName => pokeAPIName.language.name === 'fr')[0].name
        console.log(frenchName)
    } catch (error) {
        throw error
    }
})()

P.getPokemonByName(['eevee', 'ditto']) // with Promise
  .then((response) => {
    console.log(response);
  })
  .catch((error) => {
    console.log('There was an ERROR: ', error);
  });

P.getPokemonByName(34, (response, error) => { // with callback
    if(!error) {
      console.log(response);
    } else {
      console.log(error)
    }
  });

P.getResource(['/api/v2/pokemon/36', 'api/v2/berry/8', 'https://pokeapi.co/api/v2/ability/9/'])
  .then((response) => {
    console.log(response); // the getResource function accepts singles or arrays of URLs/paths
  });
```

## Configuration

Pass an Object to Pokedex in order to configure it. Available options: `protocol`, `hostName`, `versionPath`, `cacheLimit` in ms, `timeout` in ms.
Any option is optional :smile:. If no Object is passed, the Pokedex will be initialized to grab data from pokeapi.co using http with 20 seconds timeout and caching resources for 11 days. HTTPS is the default protocol.

```js
import Pokedex from 'pokedex-promise-v2';
const options = {
  protocol: 'https',
  hostName: 'localhost:443',
  versionPath: '/api/v2/',
  cacheLimit: 100 * 1000, // 100s
  timeout: 5 * 1000 // 5s
}
const P = new Pokedex(options);
```

## Endpoints

### Berries

Use **getBerryByName** to return data about a specific berry.
```js
  P.getBerryByName('cheri')
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getBerryFirmnessByName** to return data about the firmness of a specific berry.
```js
  P.getBerryFirmnessByName('very-soft')
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getBerryFlavorByName** to return data about the flavor of a specific berry.
```js
  P.getBerryFlavorByName('spicy')
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

**Array** as a parameter example. It can be a mixed array.
This method fetches data asynchronously. So it is quite fast :smile:
```js
  P.getBerryByName(['cheri', 'chesto', 5])
    .then((response) => {
      console.log(response);
    })
  // response will be an Array containing 3 Objects
  // response.forEach((item) => {console.log(item.size)}) // 80,50,20
```

### Contests

Use **getContestTypeByName** to return data about the effects of moves when used in contests.
```js
  P.getContestTypeByName('cool')
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getContestEffectById** to return data about the effects of moves when used in contests.
```js
  P.getContestEffectById(1)
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getSuperContestEffectById** to return data about the effects of moves when used in super contests.
```js
  P.getSuperContestEffectById(1)
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```
### Encounters

Use **getEncounterMethodByName** to return data about the conditions in which a trainer may encounter a pokemon in the wild.
```js
  P.getEncounterMethodByName("walk")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getEncounterConditionByName** to return data that affects which pokemon might appear in the wild.
```js
  P.getEncounterConditionByName("swarm")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getEncounterConditionValueByName** to return data the various states that an encounter condition can have.
```js
  P.getEncounterConditionValueByName("swarm-yes")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

### Evolution

Use **getEvolutionChainById** to return data evolution chains.
```js
  P.getEvolutionChainById(1)
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getEvolutionTriggerByName** to return data about triggers which cause pokemon to evolve.
```js
  P.getEvolutionTriggerByName("level-up")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

### Games

Use **getGenerationByName** to return data about the different generations of pokemon games.
```js
  P.getGenerationByName("generation-i")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getPokedexByName** to return data about specific types of pokedexes.
```js
  P.getPokedexByName("kanto")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getVersionByName** to return data about specific versions of pokemon games.
```js
  P.getVersionByName("red")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getVersionGroupByName** to return data about specific version groups of pokemon games.
```js
  P.getVersionGroupByName("red-blue")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

### Items

Use **getItemByName** to return data about specific items.
```js
  P.getItemByName("master-ball")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getItemAttributeByName** to return data about specific item attribute.
```js
  P.getItemAttributeByName("countable")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getItemCategoryByName** to return data about specific item category.
```js
  P.getItemCategoryByName("stat-boosts")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getItemFlingEffectByName** to return data about specific item fling effect.
```js
  P.getItemFlingEffectByName("badly-poison")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getItemPocketByName** to return data about specific pockets in a players bag.
```js
  P.getItemPocketByName("misc")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

### Machines

Use **getMachineById** to return data about specific machine.
```js
  P.getMachineById(2)
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

### Moves

Use **getMoveByName** to return data about specific pokemon move.
```js
  P.getMoveByName("pound")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getMoveAilmentByName** to return data about specific pokemon move ailment.
```js
  P.getMoveAilmentByName("paralysis")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getMoveBattleStyleByName** to return data about specific pokemon move battle style.
```js
  P.getMoveBattleStyleByName("attack")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getMoveCategoryByName** to return data about specific pokemon move category.
```js
  P.getMoveCategoryByName("ailment")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getMoveDamageClassByName** to return data about specific pokemon damage class.
```js
  P.getMoveDamageClassByName("status")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getMoveLearnMethodByName** to return data about specific pokemon learn method.
```js
  P.getMoveLearnMethodByName("level-up")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getMoveTargetByName** to return data about specific pokemon move target.
```js
  P.getMoveTargetByName("specific-move")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

### Locations

Use **getLocationByName** to return data about specific pokemon location.
```js
  P.getLocationByName("sinnoh")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getLocationAreaByName** to return data about specific pokemon location area.
```js
  P.getLocationAreaByName("canalave-city-area")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getPalParkAreaByName** to return data about specific pokemon pal park area.
```js
  P.getPalParkAreaByName("forest")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getRegionByName** to return data about specific pokemon region.
```js
  P.getRegionByName("kanto")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

### Pokemon

Use **getAbilityByName** to return data about specific pokemon ability.
```js
  P.getAbilityByName("stench")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getCharacteristicById** to return data about specific pokemon characteristic.
```js
  P.getCharacteristicById(1)
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getEggGroupByName** to return data about specific pokemon egg group.
```js
  P.getEggGroupByName("monster")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getGenderByName** to return data about specific pokemon gender.
```js
  P.getGenderByName("female")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getGrowthRateByName** to return data about specific pokemon growth rate.
```js
  P.getGrowthRateByName("slow")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getNatureByName** to return data about specific pokemon nature.
```js
  P.getNatureByName("bold")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getPokeathlonStatByName** to return data about specific pokeathon stat.
```js
  P.getPokeathlonStatByName("speed")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getPokemonByName** to return data about specific pokemon.
```js
  P.getPokemonByName("butterfree")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getPokemonColorByName** to return data about specific pokemon color.
```js
  P.getPokemonColorByName("black")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getPokemonFormByName** to return data about specific pokemon form.
```js
  P.getPokemonFormByName("wormadam-plant")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getPokemonHabitatByName** to return data about specific pokemon habitat.
```js
  P.getPokemonHabitatByName("grottes")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getPokemonShapeByName** to return data about specific pokemon shape.
```js
  P.getPokemonShapeByName("ball")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getPokemonSpeciesByName** to return data about specific pokemon species.
```js
  P.getPokemonSpeciesByName("wormadam")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getStatByName** to return data about specific pokemon stat.
```js
  P.getStatByName("attack")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

Use **getTypeByName** to return data about specific pokemon type.
```js
  P.getTypeByName("ground")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

### Utility

Use **getLanguageByName** to return data about specific pokemon language.
```js
  P.getLanguageByName("ja")
    .then((response) => {
      console.log(response);
    })
    .catch((error) => {
      console.log('There was an ERROR: ', error);
    });
```

### Custom URLs and paths

Use **resource** to return data about any URL or path.

```js
  P.getResource(['/api/v2/pokemon/36', 'api/v2/berry/8', 'https://pokeapi.co/api/v2/ability/9/'])
    .then((response) => {
      console.log(response); // resource function accepts singles or arrays of URLs/paths
    });

  P.getResource('api/v2/berry/5')
    .then((response) => {
      console.log(response);
    });
```

## Root Endpoints

For each root endpoint we provide a method to get all the items contained by that endpoint. By default the method will return every item in the endpoint. If you want you can configure its offset and limit.

* `offset` is where to start. The first item that you will get. Default `0`
* `limit` is how many items you want to list. Default `100000`

**TIP**: Do not pass any config Object to your call, since you will get every item and everything will be cached to your RAM.

This call will get the list of pokemon between ID 34 and ID 44

```js
  const interval = {
    limit: 10,
    offset: 34
  }
  P.getPokemonsList(interval)
    .then((response) => {
      console.log(response);
    })
```

This is what you will get:

```json
{
  "count": 811,
  "next":  "https://pokeapi.co:443/api/v2/pokemon/?limit=11&offset=44",
  "previous": "https://pokeapi.co:443/api/v2/pokemon/?limit=11&offset=22",
  "results": [
    {
      "url": "https://pokeapi.co:443/api/v2/pokemon/34/",
      "name": "nidoking"
    },
    {
      "url": "https://pokeapi.co:443/api/v2/pokemon/35/",
      "name": "clefairy"
    },
    {
      "url": "...",
      "name": "..."
    },
    {
      "url": "https://pokeapi.co:443/api/v2/pokemon/44/",
      "name": "gloom"
    }
  ]
}
```

### List of supported root endpoints

* .getEndpointsList()
* .getBerriesList()
* .getBerriesFirmnessList()
* .getBerriesFlavorsList()
* .getContestTypesList()
* .getContestEffectsList()
* .getSuperContestEffectsList()
* .getEncounterMethodsList()
* .getEncounterConditionsList()
* .getEncounterConditionValuesList()
* .getEvolutionChainsList()
* .getEvolutionTriggersList()
* .getGenerationsList()
* .getPokedexList()
* .getVersionsList()
* .getVersionGroupsList()
* .getItemsList()
* .getItemAttributesList()
* .getItemCategoriesList()
* .getItemFlingEffectsList()
* .getItemPocketsList()
* .getMachinesList()
* .getMovesList()
* .getMoveAilmentsList()
* .getMoveBattleStylesList()
* .getMoveCategoriesList()
* .getMoveDamageClassesList()
* .getMoveLearnMethodsList()
* .getMoveTargetByName()
* .getLocationsList()
* .getLocationAreasList()
* .getPalParkAreasList()
* .getRegionsList()
* .getAbilitiesList()
* .getCharacteristicsList()
* .getEggGroupsList()
* .getGendersList()
* .getGrowthRatesList()
* .getNaturesList()
* .getPokeathlonStatsList()
* .getPokemonsList()
* .getPokemonColorsList()
* .getPokemonFormsList()
* .getPokemonHabitatsList()
* .getPokemonShapesList()
* .getPokemonSpeciesList()
* .getStatsList()
* .getTypesList()
* .getLanguagesList()

## Development

A linux environment is preferred. `bash`, `sed`, `find` are required.

```sh
npm i
npm run apidata:clone # Only if you are building for the first time
npm run apidata:sync # Only if you have already built once
npm run apidata:replace
npm run generate:types
npm run generate:main
npm run generate:jsdocs
npm t
```


================================================
FILE: dist/src/index.js
================================================
/* eslint-disable */
/*
* DO NOT MODIFY, THIS IS AUTO GENERATED
* Execute `npm run generate` to regenerate
*/
import pMap from "p-map";
import NodeCache from "node-cache";
import PokeAPIOptions from "./interfaces/PokeAPIOptions.js";
import handleError from "./utils/ErrorHandler.js";
import getJSON from "./utils/Getter.js";
export default class Pokedex {
    constructor(options) {
        this.options = new PokeAPIOptions(options, new NodeCache());
    }
    async getResource(endpoint, callback) {
        try {
            // Fail if the endpoint is not supplied
            if (!endpoint) {
                throw new Error('Param "endpoint" is required needs to be a string or array of strings');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(endpoint) && typeof endpoint !== 'string') {
                throw new Error('Param "endpoint" needs to be a string or array of strings');
            }
            /// If the user has submitted a string, return the JSON promise
            if (typeof endpoint === 'string') {
                return getJSON(this.options, endpoint, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (endpoints) => {
                const queryRes = await getJSON(this.options, endpoints);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(endpoint, mapper, { concurrency: 4 });
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    /** @deprecated - will be removed on the next version. Use {@link getResource} instead */
    async resource(endpoint, callback) {
        try {
            // Fail if the endpoint is not supplied
            if (!endpoint) {
                throw new Error('Param "endpoint" is required needs to be a string or array of strings');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(endpoint) && typeof endpoint !== 'string') {
                throw new Error('Param "endpoint" needs to be a string or array of strings');
            }
            /// If the user has submitted a string, return the JSON promise
            if (typeof endpoint === 'string') {
                return getJSON(this.options, endpoint, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (endpoints) => {
                const queryRes = await getJSON(this.options, endpoints);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(endpoint, mapper, { concurrency: 4 });
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getBerryByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getBerryFirmnessByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-firmness/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-firmness/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getBerryFlavorByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-flavor/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-flavor/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getContestTypeByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}contest-type/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}contest-type/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getContestEffectById(id, callback) {
        try {
            // Fail if the param is not supplied
            if (!id) {
                throw new Error('Param "id" is required (Must be a number or array of numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(id) && typeof id !== 'number' && typeof id !== 'string') {
                throw new Error('Param "id" must be a number or array of numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof id === 'number' || typeof id === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}contest-effect/${id}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (ids) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}contest-effect/${ids}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(id, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getSuperContestEffectById(id, callback) {
        try {
            // Fail if the param is not supplied
            if (!id) {
                throw new Error('Param "id" is required (Must be a number or array of numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(id) && typeof id !== 'number' && typeof id !== 'string') {
                throw new Error('Param "id" must be a number or array of numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof id === 'number' || typeof id === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}super-contest-effect/${id}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (ids) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}super-contest-effect/${ids}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(id, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEncounterMethodByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}encounter-method/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}encounter-method/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEncounterConditionByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}encounter-condition/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}encounter-condition/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEncounterConditionValueByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}encounter-condition-value/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}encounter-condition-value/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEvolutionChainById(id, callback) {
        try {
            // Fail if the param is not supplied
            if (!id) {
                throw new Error('Param "id" is required (Must be a number or array of numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(id) && typeof id !== 'number' && typeof id !== 'string') {
                throw new Error('Param "id" must be a number or array of numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof id === 'number' || typeof id === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}evolution-chain/${id}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (ids) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}evolution-chain/${ids}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(id, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEvolutionTriggerByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}evolution-trigger/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}evolution-trigger/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getGenerationByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}generation/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}generation/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokedexByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokedex/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokedex/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getVersionByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}version/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}version/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getVersionGroupByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}version-group/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}version-group/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemAttributeByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-attribute/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-attribute/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemCategoryByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-category/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-category/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemFlingEffectByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-fling-effect/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-fling-effect/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemPocketByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-pocket/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-pocket/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMachineById(id, callback) {
        try {
            // Fail if the param is not supplied
            if (!id) {
                throw new Error('Param "id" is required (Must be a number or array of numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(id) && typeof id !== 'number' && typeof id !== 'string') {
                throw new Error('Param "id" must be a number or array of numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof id === 'number' || typeof id === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}machine/${id}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (ids) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}machine/${ids}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(id, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveAilmentByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-ailment/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-ailment/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveBattleStyleByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-battle-style/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-battle-style/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveCategoryByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-category/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-category/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveDamageClassByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-damage-class/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-damage-class/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveLearnMethodByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-learn-method/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-learn-method/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveTargetByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-target/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-target/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getLocationByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}location/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}location/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getLocationAreaByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}location-area/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}location-area/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPalParkAreaByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pal-park-area/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pal-park-area/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getRegionByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}region/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}region/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getAbilityByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}ability/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}ability/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getCharacteristicById(id, callback) {
        try {
            // Fail if the param is not supplied
            if (!id) {
                throw new Error('Param "id" is required (Must be a number or array of numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(id) && typeof id !== 'number' && typeof id !== 'string') {
                throw new Error('Param "id" must be a number or array of numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof id === 'number' || typeof id === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}characteristic/${id}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (ids) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}characteristic/${ids}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(id, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEggGroupByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}egg-group/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}egg-group/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getGenderByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}gender/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}gender/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getGrowthRateByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}growth-rate/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}growth-rate/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getNatureByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}nature/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}nature/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokeathlonStatByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokeathlon-stat/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokeathlon-stat/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonColorByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-color/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-color/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonFormByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-form/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-form/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonHabitatByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-habitat/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-habitat/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonShapeByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-shape/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-shape/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonSpeciesByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-species/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-species/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getStatByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}stat/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}stat/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getTypeByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}type/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}type/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getLanguageByName(nameOrId, callback) {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
                throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }
            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
                throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }
            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
                return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}language/${nameOrId}/`, callback);
            }
            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds) => {
                const queryRes = await getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}language/${nameOrIds}/`);
                return queryRes;
            };
            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });
            // Invoke the callback if we have one
            if (callback) {
                callback(mappedResults);
            }
            return mappedResults;
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getBerriesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getBerriesFirmnessList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-firmness/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    /** @deprecated will be removed on a future version. Use {@link getBerriesFirmnessList} instead */
    async getBerriesFirmnesssList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-firmness/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getBerriesFlavorsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-flavor/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getContestTypesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}contest-type/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getContestEffectsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}contest-effect/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getSuperContestEffectsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}super-contest-effect/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEncounterMethodsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}encounter-method/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEncounterConditionsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}encounter-condition/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEncounterConditionValuesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}encounter-condition-value/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEvolutionChainsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}evolution-chain/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEvolutionTriggersList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}evolution-trigger/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getGenerationsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}generation/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    /** @deprecated will be removed on a future version. Use {@link getPokedexList} instead */
    async getPokedexsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokedex/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokedexList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokedex/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getVersionsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}version/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getVersionGroupsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}version-group/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemAttributesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-attribute/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemCategoriesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-category/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemFlingEffectsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-fling-effect/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getItemPocketsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}item-pocket/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMachinesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}machine/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMovesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveAilmentsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-ailment/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveBattleStylesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-battle-style/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveCategoriesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-category/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveDamageClassesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-damage-class/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveLearnMethodsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-learn-method/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getMoveTargetsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}move-target/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getLocationsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}location/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getLocationAreasList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}location-area/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPalParkAreasList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pal-park-area/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getRegionsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}region/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getAbilitiesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}ability/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getCharacteristicsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}characteristic/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEggGroupsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}egg-group/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getGendersList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}gender/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getGrowthRatesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}growth-rate/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getNaturesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}nature/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokeathlonStatsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokeathlon-stat/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonColorsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-color/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonFormsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-form/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonHabitatsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-habitat/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonShapesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-shape/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getPokemonSpeciesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}pokemon-species/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getStatsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}stat/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getTypesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}type/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getLanguagesList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}language/?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    async getEndpointsList(interval, callback) {
        try {
            let { limit, offset } = this.options;
            if (interval) {
                if (interval.hasOwnProperty('limit')) {
                    limit = interval.limit;
                }
                if (interval.hasOwnProperty('offset')) {
                    offset = interval.offset;
                }
            }
            return getJSON(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}?limit=${limit}&offset=${offset}`, callback);
        }
        catch (error) {
            handleError(error, callback);
        }
    }
    /** Retrieve the configs used */
    getConfig() {
        return this.options;
    }
    /** Retuns the current number of entries in the cache */
    getCachedItemsCount() {
        return this.options.cache.stats.keys;
    }
    /** @deprecated use {@link getCachedItemsCount} */
    cacheSize() {
        return this.options.cache.stats.keys;
    }
    /** Deletes all keys in cache */
    clearCache() {
        this.options.cache.flushAll();
    }
}


================================================
FILE: dist/src/interfaces/PokeAPIOptions.js
================================================
class PokeAPIOptions {
    /* eslint-disable default-param-last */
    constructor(config = {}, cache) {
        this.protocol = 'https';
        this.hostName = '://pokeapi.co';
        this.versionPath = '/api/v2/';
        this.offset = 0;
        this.limit = 100000;
        this.timeout = 10 * 1000; // 10 seconds
        this.cacheLimit = 1000000 * 1000; // 11 days
        this.cache = cache;
        if (config.protocol) {
            this.protocol = config.protocol;
        }
        if (config.hostName) {
            this.hostName = `://${config.hostName}`;
        }
        if (config.versionPath) {
            this.versionPath = config.versionPath;
        }
        if (config.offset) {
            this.offset = config.offset - 1;
        }
        if (config.limit) {
            this.limit = config.limit;
        }
        if (config.timeout) {
            this.timeout = config.timeout;
        }
        if (config.cacheLimit) {
            this.cacheLimit = config.cacheLimit;
        }
    }
}
export default PokeAPIOptions;


================================================
FILE: dist/src/utils/Endpoints.js
================================================
const endpoints = [
    ['getBerryByName', 'berry'],
    ['getBerryFirmnessByName', 'berry-firmness'],
    ['getBerryFlavorByName', 'berry-flavor'],
    ['getContestTypeByName', 'contest-type'],
    ['getContestEffectById', 'contest-effect'],
    ['getSuperContestEffectById', 'super-contest-effect'],
    ['getEncounterMethodByName', 'encounter-method'],
    ['getEncounterConditionByName', 'encounter-condition'],
    ['getEncounterConditionValueByName', 'encounter-condition-value'],
    ['getEvolutionChainById', 'evolution-chain'],
    ['getEvolutionTriggerByName', 'evolution-trigger'],
    ['getGenerationByName', 'generation'],
    ['getPokedexByName', 'pokedex'],
    ['getVersionByName', 'version'],
    ['getVersionGroupByName', 'version-group'],
    ['getItemByName', 'item'],
    ['getItemAttributeByName', 'item-attribute'],
    ['getItemCategoryByName', 'item-category'],
    ['getItemFlingEffectByName', 'item-fling-effect'],
    ['getItemPocketByName', 'item-pocket'],
    ['getMachineById', 'machine'],
    ['getMoveByName', 'move'],
    ['getMoveAilmentByName', 'move-ailment'],
    ['getMoveBattleStyleByName', 'move-battle-style'],
    ['getMoveCategoryByName', 'move-category'],
    ['getMoveDamageClassByName', 'move-damage-class'],
    ['getMoveLearnMethodByName', 'move-learn-method'],
    ['getMoveTargetByName', 'move-target'],
    ['getLocationByName', 'location'],
    ['getLocationAreaByName', 'location-area'],
    ['getPalParkAreaByName', 'pal-park-area'],
    ['getRegionByName', 'region'],
    ['getAbilityByName', 'ability'],
    ['getCharacteristicById', 'characteristic'],
    ['getEggGroupByName', 'egg-group'],
    ['getGenderByName', 'gender'],
    ['getGrowthRateByName', 'growth-rate'],
    ['getNatureByName', 'nature'],
    ['getPokeathlonStatByName', 'pokeathlon-stat'],
    ['getPokemonByName', 'pokemon'],
    ['getPokemonColorByName', 'pokemon-color'],
    ['getPokemonFormByName', 'pokemon-form'],
    ['getPokemonHabitatByName', 'pokemon-habitat'],
    ['getPokemonShapeByName', 'pokemon-shape'],
    ['getPokemonSpeciesByName', 'pokemon-species'],
    ['getStatByName', 'stat'],
    ['getTypeByName', 'type'],
    ['getLanguageByName', 'language'],
];
export default endpoints;


================================================
FILE: dist/src/utils/ErrorHandler.js
================================================
/* eslint-disable no-shadow */
/* eslint-disable no-unused-vars */
function handleError(error, callback) {
    if (callback) {
        callback('Pokedex-promise-v2 error', error);
    }
    else {
        throw error;
    }
}
export default handleError;


================================================
FILE: dist/src/utils/Getter.js
================================================
/* eslint-disable import/no-unresolved */
import axios from 'axios';
import handleError from './ErrorHandler.js';
async function getJSON(values, url, 
// eslint-disable-next-line no-unused-vars
callback) {
    const options = {
        baseURL: `${values.protocol}${values.hostName}/`,
        timeout: values.timeout,
    };
    try {
        // Retrieve possible content from memory-cache
        const cachedResult = values.cache.get(url);
        // If we have in cache
        if (callback && cachedResult) {
            // Call callback without errors
            callback(cachedResult);
        }
        // Return the cache
        if (cachedResult) {
            return cachedResult;
        }
        // If we don't have in cache
        // get the data from the API
        const response = await axios.get(url, options);
        // If there is an error on the request
        if (response.status !== 200) {
            throw response;
        }
        // If everything was good
        // set the data
        const responseData = response.data;
        // Cache the object in memory-cache
        // only if cacheLimit > 0
        if (values.cacheLimit > 0) {
            values.cache.set(url, responseData, values.cacheLimit);
        }
        // If a callback is present
        if (callback) {
            // Call it, without errors
            callback(responseData);
        }
        return responseData;
    }
    catch (error) {
        handleError(error, callback);
    }
    // If we return nothing and the error handler fails
    // reject the promise
    return Promise.reject();
}
export default getJSON;


================================================
FILE: dist/src/utils/RootEndpoints.js
================================================
const rootEndpoints = [
    ['getEndpointsList', ''],
    ['getBerriesList', 'berry/'],
    ['getBerriesFirmnessList', 'berry-firmness/'],
    ['getBerriesFirmnesssList', 'berry-firmness/', '@deprecated will be removed on a future version. Use {@link getBerriesFirmnessList} instead'],
    ['getBerriesFlavorsList', 'berry-flavor/'],
    ['getContestTypesList', 'contest-type/'],
    ['getContestEffectsList', 'contest-effect/'],
    ['getSuperContestEffectsList', 'super-contest-effect/'],
    ['getEncounterMethodsList', 'encounter-method/'],
    ['getEncounterConditionsList', 'encounter-condition/'],
    ['getEncounterConditionValuesList', 'encounter-condition-value/'],
    ['getEvolutionChainsList', 'evolution-chain/'],
    ['getEvolutionTriggersList', 'evolution-trigger/'],
    ['getGenerationsList', 'generation/'],
    ['getPokedexsList', 'pokedex/', '@deprecated will be removed on a future version. Use {@link getPokedexList} instead'],
    ['getPokedexList', 'pokedex/'],
    ['getVersionsList', 'version/'],
    ['getVersionGroupsList', 'version-group/'],
    ['getItemsList', 'item/'],
    ['getItemAttributesList', 'item-attribute/'],
    ['getItemCategoriesList', 'item-category/'],
    ['getItemFlingEffectsList', 'item-fling-effect/'],
    ['getItemPocketsList', 'item-pocket/'],
    ['getMachinesList', 'machine/'],
    ['getMovesList', 'move/'],
    ['getMoveAilmentsList', 'move-ailment/'],
    ['getMoveBattleStylesList', 'move-battle-style/'],
    ['getMoveCategoriesList', 'move-category/'],
    ['getMoveDamageClassesList', 'move-damage-class/'],
    ['getMoveLearnMethodsList', 'move-learn-method/'],
    ['getMoveTargetsList', 'move-target/'],
    ['getLocationsList', 'location/'],
    ['getLocationAreasList', 'location-area/'],
    ['getPalParkAreasList', 'pal-park-area/'],
    ['getRegionsList', 'region/'],
    ['getAbilitiesList', 'ability/'],
    ['getCharacteristicsList', 'characteristic/'],
    ['getEggGroupsList', 'egg-group/'],
    ['getGendersList', 'gender/'],
    ['getGrowthRatesList', 'growth-rate/'],
    ['getNaturesList', 'nature/'],
    ['getPokeathlonStatsList', 'pokeathlon-stat/'],
    ['getPokemonsList', 'pokemon/'],
    ['getPokemonColorsList', 'pokemon-color/'],
    ['getPokemonFormsList', 'pokemon-form/'],
    ['getPokemonHabitatsList', 'pokemon-habitat/'],
    ['getPokemonShapesList', 'pokemon-shape/'],
    ['getPokemonSpeciesList', 'pokemon-species/'],
    ['getStatsList', 'stat/'],
    ['getTypesList', 'type/'],
    ['getLanguagesList', 'language/'],
];
export default rootEndpoints;


================================================
FILE: eslint.config.js
================================================
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';

export default [
  {
    ignores: ['dist/', 'types/'],
  },
  {
    files: ['src/**/*.ts'],
    languageOptions: {
      parser: tsparser,
      ecmaVersion: 2021,
      sourceType: 'module',
    },
    plugins: {
      '@typescript-eslint': tseslint,
    },
    rules: {
      ...tseslint.configs.recommended.rules,
      '@typescript-eslint/no-explicit-any': 'off',
    },
  },
];


================================================
FILE: generator/.eslintrc
================================================
{
  "rules": {
    "import/no-extraneous-dependencies": "off",
    "import/no-unresolved": "off",
    "no-console": "off",
    "no-restricted-syntax": "off",
    "no-shadow": "off",
    "no-continue": "off",
    "no-await-in-loop": "off",
    "prefer-destructuring": "off"
  }
}

================================================
FILE: generator/AddJSDocs.ts
================================================
import axios from 'axios';
import path from 'path';
import { InterfaceDeclaration, ModuleDeclaration, Project } from 'ts-morph';

import { jsdocsLabel, typeFile } from './Utils.js';

// The doc names available on the PokeAPI github repo
const docList = [
  'berries',
  'contests',
  'encounters',
  'evolution',
  'games',
  'items',
  'locations',
  'machines',
  'moves',
  'pokemon',
  'resource-lists',
  'utility',
];

// Add JSDocs to the interface and all of its properties
function addJsDoc(
  generatedInterface: InterfaceDeclaration,
  index: number,
  description: string,
  model: any,
) {
  // If it is the the root interface, add the main description to it
  if (index === 0 && description && description !== ' ') {
    const jsDocs = generatedInterface.getJsDocs();

    if (jsDocs && jsDocs[0] && jsDocs[0].getDescription()) {
      jsDocs[0].setDescription(description);
    } else {
      generatedInterface.addJsDoc({
        description,
      });
    }
  }

  // Add JSDocs to all of the properties of the interface
  for (const field of model.fields) {
    if (!field.description || field.description === ' ') {
      continue;
    }

    const property = generatedInterface.getProperty(field.name);
    const jsDocs = property?.getJsDocs();

    if (jsDocs && jsDocs[0] && jsDocs[0].getDescription()) {
      jsDocs[0].setDescription(field.description);
    } else if (property) {
      property.addJsDoc({
        description: field.description,
      });
    }
  }
}

// Load a doc from the PokeAPI docs and get the descriptions to apply to the code
async function loadDocumentation(namespace: ModuleDeclaration, docName: string) {
  const response = await axios.get(`https://raw.githubusercontent.com/PokeAPI/pokeapi.co/master/src/docs/${docName}.json`);
  const apis: any = await response.data;

  // As one doc contain multiple APIs examples, loop through them
  for (const api of apis) {
    // Loop over all of the response models, not the examples
    for (const [index, model] of api.responseModels.entries()) {
      try {
        // Quicktype has its quirks while generating the types, so those 3 lines account for them
        const generatedInterface = namespace.getInterface(model.name === 'PokemonEncounter' ? 'LocationAreaPokemonEncounter' : model.name);
        const purpleGeneratedInterface = namespace.getInterface(`Purple${model.name}`);
        const fluffyGeneratedInterface = namespace.getInterface(`Fluffy${model.name}`);

        if (generatedInterface) {
          addJsDoc(generatedInterface, index, api.description, model);
        }

        if (purpleGeneratedInterface) {
          addJsDoc(purpleGeneratedInterface, index, api.description, model);
        }

        if (fluffyGeneratedInterface) {
          addJsDoc(fluffyGeneratedInterface, index, api.description, model);
        }
      } catch (error) {
        console.log(model.name);
        console.log(error);
      }
    }
  }
}

// Timestamp
console.time(jsdocsLabel);
console.timeLog(jsdocsLabel, '- Starting to generate JSDocs...');

// Initialize the types file
const project = new Project({
  tsConfigFilePath: path.resolve('./tsconfig.json'),
});
const file = project.getSourceFileOrThrow(typeFile);

// Create the root module
const rootModule = file.getModuleOrThrow('\'pokedex-promise-v2\'');

// Create the namespace
const namespace = rootModule.getModuleOrThrow('PokeAPI');

// Top level async function
(async () => {
  // For each doc we have on the array, add the descriptions it provides
  for (const docName of docList) {
    await loadDocumentation(namespace, docName);
  }

  // Save the file
  await file.save();

  // Timestamp
  console.timeEnd(jsdocsLabel);
  console.log('JSDocs added!');
})();


================================================
FILE: generator/Main.ts
================================================
import fs from 'fs';
import path from 'path';
import { MethodDeclarationStructure, OptionalKind, Project } from 'ts-morph';

import endpoints from '../src/utils/Endpoints.js';
import rootEndpoints from '../src/utils/RootEndpoints.js';
import {
  apiMapFile, mainFile, mainLabel, typeFile,
} from './Utils.js';

console.time(mainLabel);
console.timeLog(mainLabel, '- Starting to main class...');

// Initialize the project
const project = new Project({
  tsConfigFilePath: path.resolve('./tsconfig.json'),
});

// Create the main index.ts
const indexFile = project.createSourceFile(mainFile, `/* eslint-disable */
/*
* DO NOT MODIFY, THIS IS AUTO GENERATED
* Execute \`npm run generate\` to regenerate
*/`, { overwrite: true });

// Get the types file
const declarationFile = project.getSourceFile(typeFile);

// Get the types module
const existingDeclarationModule = declarationFile.getModule('\'pokedex-promise-v2\'');

// Get the export existing export and remove them if it exists
const existingDeclarationExports = existingDeclarationModule.getExportAssignments();
if (existingDeclarationExports && existingDeclarationExports.length >= 1) {
  existingDeclarationExports[0].remove();
}

// Gets the default types class and remove it if it exists
const existingDeclarationClass = existingDeclarationModule.getClass('PokeAPI');
if (existingDeclarationClass) {
  existingDeclarationClass.remove();
}

// Create the updated class
const declarationClass = existingDeclarationModule.addClass({
  name: 'PokeAPI',
});

// Read the API Map
const apiMap = JSON.parse(fs.readFileSync(apiMapFile).toString());

// Import dependencies
indexFile.addImportDeclaration({
  defaultImport: 'pMap',
  moduleSpecifier: 'p-map',
});

indexFile.addImportDeclaration({
  defaultImport: 'NodeCache',
  moduleSpecifier: 'node-cache',
});

indexFile.addImportDeclaration({
  defaultImport: 'PokeAPITypes',
  moduleSpecifier: 'pokedex-promise-v2',
});

indexFile.addImportDeclaration({
  defaultImport: 'ListEndpointOptions',
  moduleSpecifier: './interfaces/ListEndpointOptions.js',
});

indexFile.addImportDeclaration({
  defaultImport: 'PokeAPIOptions',
  moduleSpecifier: './interfaces/PokeAPIOptions.js',
});

indexFile.addImportDeclaration({
  defaultImport: 'handleError',
  moduleSpecifier: './utils/ErrorHandler.js',
});

indexFile.addImportDeclaration({
  defaultImport: 'getJSON',
  moduleSpecifier: './utils/Getter.js',
});

// Add the main PokeAPI class
const pokeApiClass = indexFile.addClass({
  name: 'Pokedex',
}).setIsDefaultExport(true);

// Add options
pokeApiClass.addProperty({
  name: 'options',
  type: 'PokeAPIOptions',
});

// Create constructor
const classConstructor = {
  parameters: [{
    name: 'options',
    type: 'PokeAPIOptions',
    hasQuestionToken: true,
  }],
};

// Add the constructor typing to the class
pokeApiClass.addConstructor(classConstructor)
  .setBodyText('this.options = new PokeAPIOptions(options, new NodeCache());');
declarationClass.addConstructor(classConstructor);

// Timestamp
console.timeLog(mainLabel, ' - Base generated, generating methods...');

// Add the get generic resource array method
const getResourceCode = `try {
  // Fail if the endpoint is not supplied
  if (!endpoint) {
    throw new Error('Param "endpoint" is required needs to be a string or array of strings');
  }

  // Fail if the input types aren't accepted
  if (!Array.isArray(endpoint) && typeof endpoint !== 'string') {
    throw new Error('Param "endpoint" needs to be a string or array of strings');
  }

  /// If the user has submitted a string, return the JSON promise
  if (typeof endpoint === 'string') {
    return getJSON<any>(this.options, endpoint, callback);
  }

  // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
  const mapper = async (endpoints: string) => {
    const queryRes = await getJSON<any>(this.options, endpoints);
    return queryRes;
  };

  // Fetch data asynchronously to be faster
  const mappedResults = await pMap(endpoint, mapper, { concurrency: 4 });

  if (callback) {
    callback(mappedResults);
  }

  return mappedResults;
} catch (error) {
  handleError(error, callback);
}`;

let methodStructure: OptionalKind<MethodDeclarationStructure> = {
  name: 'getResource',
  isAsync: true,
  parameters: [{
    name: 'endpoint',
    type: 'string | string[]',
  },
  {
    name: 'callback',
    type: '(result: any | any[], error?: any) => any',
    hasQuestionToken: true,
  }],
  returnType: 'Promise<any | any[]>',
  overloads: [
    {
      parameters: [
        {
          name: 'endpoint',
          type: 'string',
        },
        {
          name: 'callback',
          type: '(result: any, error?: any) => any',
          hasQuestionToken: true,
        },
      ],
      returnType: 'Promise<any>',
    },
    {
      parameters: [
        {
          name: 'endpoint',
          type: 'string[]',
        },
        {
          name: 'callback',
          type: '(result: any[], error?: any) => any',
          hasQuestionToken: true,
        },
      ],
      returnType: 'Promise<any[]>',
    },
  ],
};

pokeApiClass.addMethod(methodStructure).setBodyText(getResourceCode);
// Add the declaration to the types file
// Removing the async keyword
methodStructure.isAsync = false;
declarationClass.addMethod(methodStructure);

// Add the deprecated get generic resource method for backwards compatibility
methodStructure.name = 'resource';

methodStructure.isAsync = true;
pokeApiClass.addMethod(methodStructure).setBodyText(getResourceCode)
  .addJsDoc('@deprecated - will be removed on the next version. Use {@link getResource} instead');

// Add the declaration to the types file
// Removing the async keyword
methodStructure.isAsync = false;
declarationClass.addMethod(methodStructure)
  .addJsDoc('@deprecated - will be removed on the next version. Use {@link getResource} instead');

// Add all the methods from the endpoints list,
// setting the parameters typing and binding to the correct interface and endpoint
for (const [methodName, endpoint, jsdocs] of endpoints) {
  const inputParam = methodName.match(/ByName$/) ? 'nameOrId' : 'id';
  const inputParamType = methodName.match(/ByName$/) ? 'string | number | Array<string | number>' : 'number | number[]';

  const singleParamType = methodName.match(/ByName$/) ? 'string | number' : 'number';
  const multipleParamType = methodName.match(/ByName$/) ? 'Array<string | number>' : 'number[]';

  const returnType = `PokeAPITypes.${apiMap[endpoint]}`;

  methodStructure = {
    name: methodName,
    isAsync: true,
    parameters: [{
      name: inputParam,
      type: inputParamType,
    },
    {
      name: 'callback',
      type: `((result: ${returnType}, error?: any) => any) & ((result: ${returnType}[], error?: any) => any)`,
      hasQuestionToken: true,
    }],
    returnType: `Promise<${returnType} | ${returnType}[]>`,
    overloads: [
      {
        parameters: [
          {
            name: inputParam,
            type: singleParamType,
          },
          {
            name: 'callback',
            type: `(result: ${returnType}, error?: any) => any`,
            hasQuestionToken: true,
          },
        ],
        returnType: `Promise<${returnType}>`,
      },
      {
        parameters: [
          {
            name: inputParam,
            type: multipleParamType,
          },
          {
            name: 'callback',
            type: `(result: ${returnType}[], error?: any) => any`,
            hasQuestionToken: true,
          },
        ],
        returnType: `Promise<${returnType}[]>`,
      },
    ],
  };

  const generatedMethod = pokeApiClass.addMethod(methodStructure).setBodyText(`try {
    // Fail if the param is not supplied
    if (!${inputParam}) {
      throw new Error('Param "${inputParam}" is required (Must be a ${methodName.match(/ByName$/) ? 'string, array of strings or array of string and/or numbers' : 'number or array of numbers'} )');
    }

    // Fail if the input types aren't accepted
    if (!Array.isArray(${inputParam}) && typeof ${inputParam} !== 'number' && typeof ${inputParam} !== 'string') {
    throw new Error('Param "${inputParam}" must be a ${methodName.match(/ByName$/) ? 'string, array of strings or array of string and/or numbers' : 'number or array of numbers'}');
    }

    // If the user has submitted a Name or an ID, return the JSON promise
    if (typeof ${inputParam} === 'number' || typeof ${inputParam} === 'string') {
      return getJSON<${returnType}>(this.options, \`\${this.options.protocol}\${this.options.hostName}\${this.options.versionPath}${endpoint}/\${${inputParam}}/\`, callback);
    }

    // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
    const mapper = async (${inputParam}s: ${inputParamType}) => {
      const queryRes = await getJSON<${returnType}>(this.options, \`\${this.options.protocol}\${this.options.hostName}\${this.options.versionPath}${endpoint}/\${${inputParam}s}/\`);
      return queryRes;
    };

    // Fetch data asynchronously to be faster
    const mappedResults = await pMap(${inputParam}, mapper, { concurrency: 4 });

    // Invoke the callback if we have one
    if (callback) {
      callback(mappedResults);
    }

    return mappedResults;
} catch (error) {
    handleError(error, callback);
}`);

  // Add the declaration to the types file
  // Removing the async keyword
  methodStructure.isAsync = false;
  const declaredMethod = declarationClass.addMethod(methodStructure);

  // If the method has a JSDoc, add it
  if (jsdocs) {
    generatedMethod.addJsDoc(jsdocs);
    declaredMethod.addJsDoc(jsdocs);
  }
}

// Timestamp
console.timeLog(mainLabel, ' - Normal methods completed, generating methods for root endpoints...');

// Add all the get list methods from the root endpoints list,
// setting the parameters typing and binding to the correct interface and endpoint
// Also sets correctly to a named or normal list
for (const [method, rawEndpoint, jsdocs] of rootEndpoints) {
  // Remove the last slash and add '-list' to the end
  const endpoint = `${rawEndpoint.replace(/\/$/, '')}-list`;

  // If the method doesn't have a interface, skip it
  if (!apiMap[endpoint]) {
    if (method !== 'getEndpointsList') {
      console.log('Could not found interface for: ', method);
    }
    continue;
  }

  // Infer the return type from the name
  const returnType = `PokeAPITypes.${apiMap[endpoint].includes('NamedList') ? 'NamedAPIResourceList' : 'APIResourceList'}`;

  const methodStructure = {
    name: method,
    isAsync: true,
    parameters: [{
      name: 'interval',
      type: 'ListEndpointOptions',
      hasQuestionToken: true,
    },
    {
      name: 'callback',
      type: `(result: ${returnType}, error?: any) => any`,
      hasQuestionToken: true,
    }],
    returnType: `Promise<${returnType}>`,
  };

  const generatedMethod = pokeApiClass.addMethod(methodStructure).setBodyText(`try {
    let { limit, offset } = this.options;

    if (interval) {
      if (interval.hasOwnProperty('limit')) {
        limit = interval.limit;
      }

      if (interval.hasOwnProperty('offset')) {
        offset = interval.offset;
      }
    }

    return getJSON(this.options, \`\${this.options.protocol}\${this.options.hostName}\${this.options.versionPath}${rawEndpoint}?limit=\${limit}&offset=\${offset}\`, callback);
  } catch (error) {
    handleError(error, callback);
  }`);

  // Add the declaration to the types file
  // Removing the async keyword
  methodStructure.isAsync = false;
  const declaredMethod = declarationClass.addMethod(methodStructure);

  // If the method has a JSDoc, add it
  if (jsdocs) {
    generatedMethod.addJsDoc(jsdocs);
    declaredMethod.addJsDoc(jsdocs);
  }
}

// Add method to get the list of endpoints
methodStructure = {
  name: 'getEndpointsList',
  isAsync: true,
  parameters: [{
    name: 'interval',
    type: 'ListEndpointOptions',
    hasQuestionToken: true,
  },
  {
    name: 'callback',
    type: '(result: any, error?: any) => any',
    hasQuestionToken: true,
  }],
  returnType: 'Promise<PokeAPITypes.EndpointsList>',
};

pokeApiClass.addMethod(methodStructure).setBodyText(`
try {
  let { limit, offset } = this.options;

  if (interval) {
    if (interval.hasOwnProperty('limit')) {
      limit = interval.limit;
    }

    if (interval.hasOwnProperty('offset')) {
      offset = interval.offset;
    }
  }

  return getJSON(this.options, \`\${this.options.protocol}\${this.options.hostName}\${this.options.versionPath}?limit=\${limit}&offset=\${offset}\`, callback);
} catch (error) {
  handleError(error, callback);
}`);

// Add the declaration to the types file
// Removing the async keyword
methodStructure.isAsync = false;
declarationClass.addMethod(methodStructure);

// Add method to get the config
pokeApiClass.addMethod({
  name: 'getConfig',
}).setBodyText('return this.options;').addJsDoc('Retrieve the configs used');

// Add method to get the cache size
pokeApiClass.addMethod({
  name: 'getCachedItemsCount',
}).setBodyText('return this.options.cache.stats.keys;').addJsDoc('Retuns the current number of entries in the cache');

pokeApiClass.addMethod({
  name: 'cacheSize',
}).setBodyText('return this.options.cache.stats.keys;').addJsDoc('@deprecated use {@link getCachedItemsCount}');

// Add method to clear the cache
pokeApiClass.addMethod({
  name: 'clearCache',
}).setBodyText('this.options.cache.flushAll();').addJsDoc('Deletes all keys in cache');

// Export the typing
declarationClass.getParentModule().addExportAssignment({
  expression: 'PokeAPI',
});

// Sanitize the namespaces of the declaration file and format it again
declarationClass.replaceWithText(declarationClass.getFullText().replace(/PokeAPITypes/g, 'PokeAPI'));
declarationClass.formatText();

// Top level async function
(async () => {
  // Save and compile to JS
  await indexFile.save();
  await declarationFile.save();
  await project.emit();
})();

// Timestamp
console.timeEnd(mainLabel);
console.log('Main class generated!');


================================================
FILE: generator/TypesGenerator.ts
================================================
import fs from 'fs';
import path from 'path';
import directoryTree from 'directory-tree';
import { Project, Writers } from 'ts-morph';
import {
  quicktype, InputData, JSONSchemaInput, FetchingJSONSchemaStore,
} from 'quicktype-core';

import {
  apiMapFile, schemaFolder, typesLabel, typeFile,
} from './Utils.js';

console.log(schemaFolder);
if (!fs.existsSync(schemaFolder)) {
  console.log('Schemas not found, please clone the "PokeAPI/api-data" repository on the root of this project first and change all $refs from "/schema/v2" to "api-data/data/schema/v2")');
  process.exit(1);
}

// Helper functions to interface names
function clearAndUpper(text: string) {
  return text.replace(/-/, '').toUpperCase();
}

function toPascalCase(text: string) {
  return text.replace(/(^\w|-\w)/g, clearAndUpper);
}

// A map for the methods of the class
const apiMap: Record<string, string> = {};

// The method that will string together the types and the PokeAPI class
async function generateFinalFile(types: string) {
  // Log progress...
  console.timeLog(typesLabel, '- Types generated, starting the generation of the definition file...');

  // Initialize the types file
  const project = new Project();
  const file = project.createSourceFile(typeFile, `/*
* Type definitions for pokedex-promise-v2 v4.x
* DO NOT MODIFY, THIS IS AUTO GENERATED
* Code by: HRKings <https://github.com/HRKings/>
* And: Christian Garza <https://github.com/C-Garza/>
* Code inspired by: Mudkip <https://github.com/mudkipme/>
* Execute \`npm run generate:types\` to regenerate
*/`, { overwrite: true });

  // Create the root module
  const rootModule = file.addModule({
    name: '\'pokedex-promise-v2\'',
  });

  // Create the namespace
  const namespace = rootModule.addModule({
    name: 'PokeAPI',
  });

  // Write the interfaces to the namespace
  namespace.setBodyText(types);

  // Remove interfaces that are wrongly generated
  namespace.getInterface('EvolutionChainElement')?.remove();
  namespace.getInterface('ResultElement')?.remove();
  namespace.getInterface('GenerationElement')?.remove();
  namespace.getInterface('VersionGroupNamedList')?.remove();

  // Replace the wrong definitions with the correct ones
  namespace.setBodyText(namespace.getBodyText()
    .replace(/ResultElement/g, 'APIResource')
    .replace(/EvolutionChainElement/g, 'APIResource')
    .replace(/GenerationElement/g, 'NamedAPIResource'));

  // Format the namespace to be correctly indented
  namespace.formatText();

  // Add the root endpoint interval
  rootModule.addInterface({
    name: 'ListEndpointOptions',
    properties: [{
      name: 'offset',
      type: 'number',
      hasQuestionToken: true,
      docs: ['The offset to be used in the request'],
    }, {
      name: 'limit',
      type: 'number',
      hasQuestionToken: true,
      docs: ['The limit to be used in the request'],
    }, {
      name: 'cacheLimit',
      type: 'number',
      hasQuestionToken: true,
      docs: ['The limit of the cache in milliseconds'],
    }],
  });

  // Add the options interface
  rootModule.addInterface({
    name: 'PokeAPIOptions',
    properties: [{
      name: 'protocol',
      type: Writers.unionType('\'https\'', '\'http\''),
      hasQuestionToken: true,
      docs: ['The protocol to be used',
        '@default \'https\''],
    }, {
      name: 'hostName',
      type: 'string',
      hasQuestionToken: true,
      docs: ['The hostname of the PokeAPI instance',
        '@default \'pokeapi.co\''],
    }, {
      name: 'versionPath',
      type: 'string',
      hasQuestionToken: true,
      docs: ['The version path of the API',
        '@default \'/api/v2/\''],
    }, {
      name: 'offset',
      type: 'number',
      hasQuestionToken: true,
      docs: ['The offset to be used in list requests',
        '@default 0'],
    }, {
      name: 'limit',
      type: 'number',
      hasQuestionToken: true,
      docs: ['The limit to be used in list requests',
        '@default 100000'],
    }, {
      name: 'timeout',
      type: 'number',
      hasQuestionToken: true,
      docs: ['The timeout of a response in milliseconds',
        '@default 10 * 1000 // (10 seconds)'],
    }, {
      name: 'cacheLimit',
      type: 'number',
      hasQuestionToken: true,
      docs: ['The limit of the cache in milliseconds',
        '@default 1000000 * 1000 // (11 days)'],
    }],
  });

  // Write the file
  await file.save();

  // Write the API Map
  fs.writeFileSync(apiMapFile, JSON.stringify(apiMap, null, 2));

  // Log progress...
  console.timeEnd(typesLabel);
  console.log('Definition file created!');
}

// Log start
console.time(typesLabel);
console.timeLog(typesLabel, '- Starting to generate types...');

// Init quicktype stuff
const schemaInput = new JSONSchemaInput(new FetchingJSONSchemaStore());
const inputData = new InputData();

// Gets schema file and adds it to schema source, outputs file at end
async function quicktypeMain(jsonSchema: string, basename: string) {
  // Add a single schema file to the schemaInput
  await schemaInput.addSource({ name: basename, schema: jsonSchema });

  // If its the last schema to process
  if (basename === 'VersionGroupNamedList') {
    // Adds the last file to the schema
    inputData.addInput(schemaInput);

    // Combines final large schema file into d.ts file
    const qt = await quicktype({
      inputData,
      lang: 'typescript',
      rendererOptions: {
        'just-types': 'true',
      },
    });

    await generateFinalFile(qt.lines.join('\n').replace(/export /g, ''));
  }
}

// First pass through directory tree to make sure standalone files
// are added to schema source first
const tree = directoryTree(schemaFolder, { extensions: /\.json$/, normalizePath: true });
tree.children.forEach((child) => {
  if (!child.children) {
    // Get the file name
    let basename = path.basename(child.path, '.json').replace(/_/g, '-');

    // If the interface is the one containing all the endpoints, rename the interface
    if (basename === 'index') {
      basename = 'EndpointsList';
    } else {
      basename = toPascalCase(basename);
    }

    // Read all the schema file
    const jsonSchema = fs.readFileSync(child.path, 'utf8');
    quicktypeMain(jsonSchema, basename);
  }
});

// Loops through schema directory with main logic
directoryTree(schemaFolder, { extensions: /\.json$/, normalizePath: true }, (item) => {
  // Split the path, to get the folder names later
  const paths = item.path.split('/').reverse();

  // Don't add the standalone files again to the schema source
  // also, don't parse the -1 folder
  if (paths[1] !== 'v2' && !item.path.includes('move-ailment/-1')) {
    // The endpoint path, as in the endpoints list
    let basename: string;
    // The name of the generated interface/type
    let interfaceName: string;

    // Handle special case
    if (item.path.includes('pokemon/$id/encounters')) {
      basename = 'pokemon-encounter';
      interfaceName = 'PokemonEncounter';
    } else if (item.path.includes('$id')) {
      // If the scheme is the wanted one, pick the name of two folder above
      // eg.: 'pokemon/$id/index.json', picks the "pokemon"
      basename = paths[2];
      interfaceName = toPascalCase(basename);
    } else {
      // Gets one folder above (used for the resource lists)
      // eg. 'pokemon/index.js', picks the "pokemon"
      // and adds 'List' to the interface name, eg. 'PokemonList'
      basename = `${paths[1]}-list`;
      interfaceName = toPascalCase(basename);
    }

    // Register to the API map to use later on the methods
    apiMap[basename] = interfaceName;

    // Read all the schema file
    const jsonSchema = fs.readFileSync(item.path, 'utf8');

    // If the interface contains named resources and is a list, rename the interface
    if (interfaceName.includes('List') && jsonSchema.includes('named_api_resource_list.json')) {
      interfaceName = interfaceName.replace('List', 'NamedList');
      apiMap[basename] = interfaceName;
    }

    quicktypeMain(jsonSchema, interfaceName);
  }
});


================================================
FILE: generator/Utils.ts
================================================
/* eslint-disable no-underscore-dangle */
import { fileURLToPath } from 'url';
import path, { dirname } from 'path';

export const __filename = fileURLToPath(import.meta.url);
export const __dirname = dirname(__filename);

// Paths that will be used
export const typeFile = path.resolve(__dirname, '../../types/index.d.ts');
export const mainFile = path.resolve(__dirname, '../../src/index.ts');
export const apiMapFile = path.join(__dirname, 'apiMap.json');
export const schemaFolder = path.resolve(__dirname, '../../api-data/data/schema/v2');

// Timer labels
export const typesLabel = 'Types Generator';
export const mainLabel = 'Main Generator';
export const jsdocsLabel = 'JSDocs Generator';


================================================
FILE: generator/tsconfig.json
================================================
{
  "compilerOptions": {
    "target": "es2020",
    "module": "es2020",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "lib": [
      "es2020",
      "dom"
    ],
    "outDir": "../dist"
  },
  "include": [
    "./**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}


================================================
FILE: package.json
================================================
{
  "name": "pokedex-promise-v2",
  "type": "module",
  "version": "4.2.1",
  "description": "A library used to get information about Pokemons.",
  "engines": {
    "node": ">=18"
  },
  "main": "dist/src/index.js",
  "typings": "types/index.d.ts",
  "scripts": {
    "doctoc": "doctoc .",
    "test": "tsc && mocha dist/test/",
    "testjs": "(cd test/js && npm i ../.. && node index.js)",
    "apidata:clone": "git clone https://github.com/PokeAPI/api-data.git",
    "apidata:sync": "git -C api-data reset --hard HEAD && git -C api-data pull",
    "apidata:replace": "find api-data/data/schema -type f -exec sed -i -e s:/schema/v2:api-data/data/schema/v2:g {} +",
    "generate:types": "tsc -p generator/ && node dist/generator/TypesGenerator.js",
    "generate:main": "tsc -p generator/ && node dist/generator/Main.js",
    "generate:jsdocs": "tsc -p generator/ && node dist/generator/AddJSDocs.js",
    "lint": "eslint src/ --fix",
    "generate:all": "(npm run apidata:clone || true) && npm run apidata:sync && npm run apidata:replace && npm run generate:types && npm run generate:main && npm run generate:jsdocs"
  },
  "files": [
    "dist/src/",
    "types"
  ],
  "types": "types/index.d.ts",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/PokeAPI/pokedex-promise-v2"
  },
  "keywords": [
    "pokedex",
    "pokemon",
    "nintendo",
    "promise",
    "pokeapi"
  ],
  "author": "Thomas Asadurian <Tasadurian@gmail.com> (http://thetommytwitch.github.io/)",
  "contributors": [
    "Alessandro Pezzé <igougi.ui@gmail.com> (https://github.com/Naramsim)",
    "Christian Garza (https://github.com/C-Garza)",
    "Helton Reis (https://github.com/HRKings)"
  ],
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/PokeAPI/pokedex-promise-v2/issues"
  },
  "homepage": "https://github.com/PokeAPI/pokedex-promise-v2#readme",
  "dependencies": {
    "axios": "^1.13.5",
    "node-cache": "^5.1.2",
    "p-map": "^7.0.4"
  },
  "devDependencies": {
    "@types/chai": "^4.3.20",
    "@types/chai-as-promised": "^7.1.8",
    "@types/chai-things": "^0.0.38",
    "@types/memory-cache": "^0.2.6",
    "@types/mocha": "^10.0.10",
    "@types/node": "^20.19.33",
    "@typescript-eslint/eslint-plugin": "^8.56.1",
    "@typescript-eslint/parser": "^8.56.1",
    "chai": "^4.5.0",
    "chai-as-promised": "^7.1.2",
    "chai-things": "^0.2.0",
    "directory-tree": "^3.6.0",
    "doctoc": "^2.3.0",
    "eslint": "^10.0.2",
    "lodash": "^4.17.23",
    "mocha": "^11.7.5",
    "quicktype-core": "^23.2.6",
    "ts-morph": "^27.0.2",
    "typescript": "^5.9.3"
  },
  "packageManager": "pnpm@9.15.4",
  "overrides": {
    "minimatch": ">=10.2.3",
    "diff": ">=8.0.3",
    "serialize-javascript": ">=7.0.3",
    "underscore": ">=1.13.8",
    "flatted": ">=3.4.0"
  },
  "pnpm": {
    "overrides": {
      "braces@<3.0.3": ">=3.0.3",
      "micromatch@<4.0.8": ">=4.0.8",
      "axios@>=1.0.0 <1.8.2": ">=1.8.2",
      "cross-spawn@>=7.0.0 <7.0.5": ">=7.0.5",
      "brace-expansion@>=1.0.0 <=1.1.11": ">=1.1.12",
      "brace-expansion@>=2.0.0 <=2.0.1": ">=2.0.2",
      "form-data@>=4.0.0 <4.0.4": ">=4.0.4",
      "axios@<1.12.0": ">=1.12.0",
      "minimatch@<10.2.3": ">=10.2.3",
      "diff@>=6.0.0 <8.0.3": ">=8.0.3",
      "js-yaml@>=4.0.0 <4.1.1": ">=4.1.1",
      "serialize-javascript@<=7.0.2": ">=7.0.3",
      "underscore@<=1.13.7": ">=1.13.8",
      "flatted@<3.4.0": ">=3.4.0"
    }
  }
}


================================================
FILE: src/index.ts
================================================
/*
* DO NOT MODIFY, THIS IS AUTO GENERATED
* Execute `npm run generate` to regenerate
*/
import pMap from "p-map";
import NodeCache from "node-cache";
import PokeAPITypes from "pokedex-promise-v2";
import ListEndpointOptions from "./interfaces/ListEndpointOptions.js";
import PokeAPIOptions from "./interfaces/PokeAPIOptions.js";
import handleError from "./utils/ErrorHandler.js";
import getJSON from "./utils/Getter.js";

export default class Pokedex {
    options: PokeAPIOptions;

    constructor(options?: PokeAPIOptions) {
        this.options = new PokeAPIOptions(options, new NodeCache());
    }

    getResource(endpoint: string, callback?: (result: any, error?: any) => any): Promise<any>;
    getResource(endpoint: string[], callback?: (result: any[], error?: any) => any): Promise<any[]>;
    async getResource(endpoint: string | string[], callback?: (result: any | any[], error?: any) => any): Promise<any | any[]> {
        try {
          // Fail if the endpoint is not supplied
          if (!endpoint) {
            throw new Error('Param "endpoint" is required needs to be a string or array of strings');
          }

          // Fail if the input types aren't accepted
          if (!Array.isArray(endpoint) && typeof endpoint !== 'string') {
            throw new Error('Param "endpoint" needs to be a string or array of strings');
          }

          /// If the user has submitted a string, return the JSON promise
          if (typeof endpoint === 'string') {
            return getJSON<any>(this.options, endpoint, callback);
          }

          // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
          const mapper = async (endpoints: string) => {
            const queryRes = await getJSON<any>(this.options, endpoints);
            return queryRes;
          };

          // Fetch data asynchronously to be faster
          const mappedResults = await pMap(endpoint, mapper, { concurrency: 4 });

          if (callback) {
            callback(mappedResults);
          }

          return mappedResults;
        } catch (error) {
          handleError(error, callback);
        }
    }

    resource(endpoint: string, callback?: (result: any, error?: any) => any): Promise<any>;
    resource(endpoint: string[], callback?: (result: any[], error?: any) => any): Promise<any[]>;
    /** @deprecated - will be removed on the next version. Use {@link getResource} instead */
    async resource(endpoint: string | string[], callback?: (result: any | any[], error?: any) => any): Promise<any | any[]> {
        try {
          // Fail if the endpoint is not supplied
          if (!endpoint) {
            throw new Error('Param "endpoint" is required needs to be a string or array of strings');
          }

          // Fail if the input types aren't accepted
          if (!Array.isArray(endpoint) && typeof endpoint !== 'string') {
            throw new Error('Param "endpoint" needs to be a string or array of strings');
          }

          /// If the user has submitted a string, return the JSON promise
          if (typeof endpoint === 'string') {
            return getJSON<any>(this.options, endpoint, callback);
          }

          // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
          const mapper = async (endpoints: string) => {
            const queryRes = await getJSON<any>(this.options, endpoints);
            return queryRes;
          };

          // Fetch data asynchronously to be faster
          const mappedResults = await pMap(endpoint, mapper, { concurrency: 4 });

          if (callback) {
            callback(mappedResults);
          }

          return mappedResults;
        } catch (error) {
          handleError(error, callback);
        }
    }

    getBerryByName(nameOrId: string | number, callback?: (result: PokeAPITypes.Berry, error?: any) => any): Promise<PokeAPITypes.Berry>;
    getBerryByName(nameOrId: Array<string | number>, callback?: (result: PokeAPITypes.Berry[], error?: any) => any): Promise<PokeAPITypes.Berry[]>;
    async getBerryByName(nameOrId: string | number | Array<string | number>, callback?: ((result: PokeAPITypes.Berry, error?: any) => any) & ((result: PokeAPITypes.Berry[], error?: any) => any)): Promise<PokeAPITypes.Berry | PokeAPITypes.Berry[]> {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
              throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }

            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
            throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }

            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
              return getJSON<PokeAPITypes.Berry>(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry/${nameOrId}/`, callback);
            }

            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds: string | number | Array<string | number>) => {
              const queryRes = await getJSON<PokeAPITypes.Berry>(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry/${nameOrIds}/`);
              return queryRes;
            };

            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });

            // Invoke the callback if we have one
            if (callback) {
              callback(mappedResults);
            }

            return mappedResults;
        } catch (error) {
            handleError(error, callback);
        }
    }

    getBerryFirmnessByName(nameOrId: string | number, callback?: (result: PokeAPITypes.BerryFirmness, error?: any) => any): Promise<PokeAPITypes.BerryFirmness>;
    getBerryFirmnessByName(nameOrId: Array<string | number>, callback?: (result: PokeAPITypes.BerryFirmness[], error?: any) => any): Promise<PokeAPITypes.BerryFirmness[]>;
    async getBerryFirmnessByName(nameOrId: string | number | Array<string | number>, callback?: ((result: PokeAPITypes.BerryFirmness, error?: any) => any) & ((result: PokeAPITypes.BerryFirmness[], error?: any) => any)): Promise<PokeAPITypes.BerryFirmness | PokeAPITypes.BerryFirmness[]> {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
              throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }

            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
            throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }

            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
              return getJSON<PokeAPITypes.BerryFirmness>(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-firmness/${nameOrId}/`, callback);
            }

            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds: string | number | Array<string | number>) => {
              const queryRes = await getJSON<PokeAPITypes.BerryFirmness>(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-firmness/${nameOrIds}/`);
              return queryRes;
            };

            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });

            // Invoke the callback if we have one
            if (callback) {
              callback(mappedResults);
            }

            return mappedResults;
        } catch (error) {
            handleError(error, callback);
        }
    }

    getBerryFlavorByName(nameOrId: string | number, callback?: (result: PokeAPITypes.BerryFlavor, error?: any) => any): Promise<PokeAPITypes.BerryFlavor>;
    getBerryFlavorByName(nameOrId: Array<string | number>, callback?: (result: PokeAPITypes.BerryFlavor[], error?: any) => any): Promise<PokeAPITypes.BerryFlavor[]>;
    async getBerryFlavorByName(nameOrId: string | number | Array<string | number>, callback?: ((result: PokeAPITypes.BerryFlavor, error?: any) => any) & ((result: PokeAPITypes.BerryFlavor[], error?: any) => any)): Promise<PokeAPITypes.BerryFlavor | PokeAPITypes.BerryFlavor[]> {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
              throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }

            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
            throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }

            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
              return getJSON<PokeAPITypes.BerryFlavor>(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-flavor/${nameOrId}/`, callback);
            }

            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds: string | number | Array<string | number>) => {
              const queryRes = await getJSON<PokeAPITypes.BerryFlavor>(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}berry-flavor/${nameOrIds}/`);
              return queryRes;
            };

            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });

            // Invoke the callback if we have one
            if (callback) {
              callback(mappedResults);
            }

            return mappedResults;
        } catch (error) {
            handleError(error, callback);
        }
    }

    getContestTypeByName(nameOrId: string | number, callback?: (result: PokeAPITypes.ContestType, error?: any) => any): Promise<PokeAPITypes.ContestType>;
    getContestTypeByName(nameOrId: Array<string | number>, callback?: (result: PokeAPITypes.ContestType[], error?: any) => any): Promise<PokeAPITypes.ContestType[]>;
    async getContestTypeByName(nameOrId: string | number | Array<string | number>, callback?: ((result: PokeAPITypes.ContestType, error?: any) => any) & ((result: PokeAPITypes.ContestType[], error?: any) => any)): Promise<PokeAPITypes.ContestType | PokeAPITypes.ContestType[]> {
        try {
            // Fail if the param is not supplied
            if (!nameOrId) {
              throw new Error('Param "nameOrId" is required (Must be a string, array of strings or array of string and/or numbers )');
            }

            // Fail if the input types aren't accepted
            if (!Array.isArray(nameOrId) && typeof nameOrId !== 'number' && typeof nameOrId !== 'string') {
            throw new Error('Param "nameOrId" must be a string, array of strings or array of string and/or numbers');
            }

            // If the user has submitted a Name or an ID, return the JSON promise
            if (typeof nameOrId === 'number' || typeof nameOrId === 'string') {
              return getJSON<PokeAPITypes.ContestType>(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}contest-type/${nameOrId}/`, callback);
            }

            // If the user has submitted an Array return a new promise which will resolve when all getJSON calls are ended
            const mapper = async (nameOrIds: string | number | Array<string | number>) => {
              const queryRes = await getJSON<PokeAPITypes.ContestType>(this.options, `${this.options.protocol}${this.options.hostName}${this.options.versionPath}contest-type/${nameOrIds}/`);
              return queryRes;
            };

            // Fetch data asynchronously to be faster
            const mappedResults = await pMap(nameOrId, mapper, { concurrency: 4 });

            // Invoke the callback if we have one
            if (callback) {
              callback(mappedResults);
            }

            return mappedResults;
        } catch (error) {
            handleError(error, callback);
        }
    }

    getContestEffectById(id: number, callback?: (result: PokeAPITypes.ContestEffect, error?: any) => any): Promise<PokeAPITypes.ContestEffect>;
    getContestEffectById(id: number[], callback?: (result: PokeAPITypes.ContestEffect[], error?: any) => any): Promise<PokeAPITypes.ContestEffect[]>;
    async getContestEffectById(id: number | number[], callback?: ((result: PokeAPITypes.ContestEffect, error?: any) => any) & ((result: PokeAPITypes.ContestEffect[], error?: any) => any)): Promise<PokeAPITypes.ContestEffect | PokeAPITypes.ContestEffect[]> {
        try {
            // Fail if the param is not supplied
            if (!id) {
              throw new Error('Param "id" is required (Must be a number or array of numbers )');
            }

            // Fail if the input types aren't accepted
Download .txt
gitextract__53gir3x/

├── .editorconfig
├── .github/
│   └── workflows/
│       └── test.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── LICENSE
├── README.md
├── dist/
│   └── src/
│       ├── index.js
│       ├── interfaces/
│       │   └── PokeAPIOptions.js
│       └── utils/
│           ├── Endpoints.js
│           ├── ErrorHandler.js
│           ├── Getter.js
│           └── RootEndpoints.js
├── eslint.config.js
├── generator/
│   ├── .eslintrc
│   ├── AddJSDocs.ts
│   ├── Main.ts
│   ├── TypesGenerator.ts
│   ├── Utils.ts
│   └── tsconfig.json
├── package.json
├── src/
│   ├── index.ts
│   ├── interfaces/
│   │   ├── ListEndpointOptions.d.ts
│   │   └── PokeAPIOptions.ts
│   └── utils/
│       ├── Endpoints.ts
│       ├── ErrorHandler.ts
│       ├── Getter.ts
│       └── RootEndpoints.ts
├── test/
│   ├── .eslintrc
│   ├── Async.spec.ts
│   ├── Base.spec.ts
│   ├── ClearCache.spec.ts
│   ├── CommonCalls.spec.ts
│   ├── CustomUncommonCalls.spec.ts
│   ├── Resource.spec.ts
│   └── RootEndpoints.spec.ts
├── tsconfig.json
└── types/
    └── index.d.ts
Download .txt
SYMBOL INDEX (382 symbols across 12 files)

FILE: dist/src/index.js
  class Pokedex (line 11) | class Pokedex {
    method constructor (line 12) | constructor(options) {
    method getResource (line 15) | async getResource(endpoint, callback) {
    method resource (line 46) | async resource(endpoint, callback) {
    method getBerryByName (line 76) | async getBerryByName(nameOrId, callback) {
    method getBerryFirmnessByName (line 107) | async getBerryFirmnessByName(nameOrId, callback) {
    method getBerryFlavorByName (line 138) | async getBerryFlavorByName(nameOrId, callback) {
    method getContestTypeByName (line 169) | async getContestTypeByName(nameOrId, callback) {
    method getContestEffectById (line 200) | async getContestEffectById(id, callback) {
    method getSuperContestEffectById (line 231) | async getSuperContestEffectById(id, callback) {
    method getEncounterMethodByName (line 262) | async getEncounterMethodByName(nameOrId, callback) {
    method getEncounterConditionByName (line 293) | async getEncounterConditionByName(nameOrId, callback) {
    method getEncounterConditionValueByName (line 324) | async getEncounterConditionValueByName(nameOrId, callback) {
    method getEvolutionChainById (line 355) | async getEvolutionChainById(id, callback) {
    method getEvolutionTriggerByName (line 386) | async getEvolutionTriggerByName(nameOrId, callback) {
    method getGenerationByName (line 417) | async getGenerationByName(nameOrId, callback) {
    method getPokedexByName (line 448) | async getPokedexByName(nameOrId, callback) {
    method getVersionByName (line 479) | async getVersionByName(nameOrId, callback) {
    method getVersionGroupByName (line 510) | async getVersionGroupByName(nameOrId, callback) {
    method getItemByName (line 541) | async getItemByName(nameOrId, callback) {
    method getItemAttributeByName (line 572) | async getItemAttributeByName(nameOrId, callback) {
    method getItemCategoryByName (line 603) | async getItemCategoryByName(nameOrId, callback) {
    method getItemFlingEffectByName (line 634) | async getItemFlingEffectByName(nameOrId, callback) {
    method getItemPocketByName (line 665) | async getItemPocketByName(nameOrId, callback) {
    method getMachineById (line 696) | async getMachineById(id, callback) {
    method getMoveByName (line 727) | async getMoveByName(nameOrId, callback) {
    method getMoveAilmentByName (line 758) | async getMoveAilmentByName(nameOrId, callback) {
    method getMoveBattleStyleByName (line 789) | async getMoveBattleStyleByName(nameOrId, callback) {
    method getMoveCategoryByName (line 820) | async getMoveCategoryByName(nameOrId, callback) {
    method getMoveDamageClassByName (line 851) | async getMoveDamageClassByName(nameOrId, callback) {
    method getMoveLearnMethodByName (line 882) | async getMoveLearnMethodByName(nameOrId, callback) {
    method getMoveTargetByName (line 913) | async getMoveTargetByName(nameOrId, callback) {
    method getLocationByName (line 944) | async getLocationByName(nameOrId, callback) {
    method getLocationAreaByName (line 975) | async getLocationAreaByName(nameOrId, callback) {
    method getPalParkAreaByName (line 1006) | async getPalParkAreaByName(nameOrId, callback) {
    method getRegionByName (line 1037) | async getRegionByName(nameOrId, callback) {
    method getAbilityByName (line 1068) | async getAbilityByName(nameOrId, callback) {
    method getCharacteristicById (line 1099) | async getCharacteristicById(id, callback) {
    method getEggGroupByName (line 1130) | async getEggGroupByName(nameOrId, callback) {
    method getGenderByName (line 1161) | async getGenderByName(nameOrId, callback) {
    method getGrowthRateByName (line 1192) | async getGrowthRateByName(nameOrId, callback) {
    method getNatureByName (line 1223) | async getNatureByName(nameOrId, callback) {
    method getPokeathlonStatByName (line 1254) | async getPokeathlonStatByName(nameOrId, callback) {
    method getPokemonByName (line 1285) | async getPokemonByName(nameOrId, callback) {
    method getPokemonColorByName (line 1316) | async getPokemonColorByName(nameOrId, callback) {
    method getPokemonFormByName (line 1347) | async getPokemonFormByName(nameOrId, callback) {
    method getPokemonHabitatByName (line 1378) | async getPokemonHabitatByName(nameOrId, callback) {
    method getPokemonShapeByName (line 1409) | async getPokemonShapeByName(nameOrId, callback) {
    method getPokemonSpeciesByName (line 1440) | async getPokemonSpeciesByName(nameOrId, callback) {
    method getStatByName (line 1471) | async getStatByName(nameOrId, callback) {
    method getTypeByName (line 1502) | async getTypeByName(nameOrId, callback) {
    method getLanguageByName (line 1533) | async getLanguageByName(nameOrId, callback) {
    method getBerriesList (line 1564) | async getBerriesList(interval, callback) {
    method getBerriesFirmnessList (line 1581) | async getBerriesFirmnessList(interval, callback) {
    method getBerriesFirmnesssList (line 1599) | async getBerriesFirmnesssList(interval, callback) {
    method getBerriesFlavorsList (line 1616) | async getBerriesFlavorsList(interval, callback) {
    method getContestTypesList (line 1633) | async getContestTypesList(interval, callback) {
    method getContestEffectsList (line 1650) | async getContestEffectsList(interval, callback) {
    method getSuperContestEffectsList (line 1667) | async getSuperContestEffectsList(interval, callback) {
    method getEncounterMethodsList (line 1684) | async getEncounterMethodsList(interval, callback) {
    method getEncounterConditionsList (line 1701) | async getEncounterConditionsList(interval, callback) {
    method getEncounterConditionValuesList (line 1718) | async getEncounterConditionValuesList(interval, callback) {
    method getEvolutionChainsList (line 1735) | async getEvolutionChainsList(interval, callback) {
    method getEvolutionTriggersList (line 1752) | async getEvolutionTriggersList(interval, callback) {
    method getGenerationsList (line 1769) | async getGenerationsList(interval, callback) {
    method getPokedexsList (line 1787) | async getPokedexsList(interval, callback) {
    method getPokedexList (line 1804) | async getPokedexList(interval, callback) {
    method getVersionsList (line 1821) | async getVersionsList(interval, callback) {
    method getVersionGroupsList (line 1838) | async getVersionGroupsList(interval, callback) {
    method getItemsList (line 1855) | async getItemsList(interval, callback) {
    method getItemAttributesList (line 1872) | async getItemAttributesList(interval, callback) {
    method getItemCategoriesList (line 1889) | async getItemCategoriesList(interval, callback) {
    method getItemFlingEffectsList (line 1906) | async getItemFlingEffectsList(interval, callback) {
    method getItemPocketsList (line 1923) | async getItemPocketsList(interval, callback) {
    method getMachinesList (line 1940) | async getMachinesList(interval, callback) {
    method getMovesList (line 1957) | async getMovesList(interval, callback) {
    method getMoveAilmentsList (line 1974) | async getMoveAilmentsList(interval, callback) {
    method getMoveBattleStylesList (line 1991) | async getMoveBattleStylesList(interval, callback) {
    method getMoveCategoriesList (line 2008) | async getMoveCategoriesList(interval, callback) {
    method getMoveDamageClassesList (line 2025) | async getMoveDamageClassesList(interval, callback) {
    method getMoveLearnMethodsList (line 2042) | async getMoveLearnMethodsList(interval, callback) {
    method getMoveTargetsList (line 2059) | async getMoveTargetsList(interval, callback) {
    method getLocationsList (line 2076) | async getLocationsList(interval, callback) {
    method getLocationAreasList (line 2093) | async getLocationAreasList(interval, callback) {
    method getPalParkAreasList (line 2110) | async getPalParkAreasList(interval, callback) {
    method getRegionsList (line 2127) | async getRegionsList(interval, callback) {
    method getAbilitiesList (line 2144) | async getAbilitiesList(interval, callback) {
    method getCharacteristicsList (line 2161) | async getCharacteristicsList(interval, callback) {
    method getEggGroupsList (line 2178) | async getEggGroupsList(interval, callback) {
    method getGendersList (line 2195) | async getGendersList(interval, callback) {
    method getGrowthRatesList (line 2212) | async getGrowthRatesList(interval, callback) {
    method getNaturesList (line 2229) | async getNaturesList(interval, callback) {
    method getPokeathlonStatsList (line 2246) | async getPokeathlonStatsList(interval, callback) {
    method getPokemonsList (line 2263) | async getPokemonsList(interval, callback) {
    method getPokemonColorsList (line 2280) | async getPokemonColorsList(interval, callback) {
    method getPokemonFormsList (line 2297) | async getPokemonFormsList(interval, callback) {
    method getPokemonHabitatsList (line 2314) | async getPokemonHabitatsList(interval, callback) {
    method getPokemonShapesList (line 2331) | async getPokemonShapesList(interval, callback) {
    method getPokemonSpeciesList (line 2348) | async getPokemonSpeciesList(interval, callback) {
    method getStatsList (line 2365) | async getStatsList(interval, callback) {
    method getTypesList (line 2382) | async getTypesList(interval, callback) {
    method getLanguagesList (line 2399) | async getLanguagesList(interval, callback) {
    method getEndpointsList (line 2416) | async getEndpointsList(interval, callback) {
    method getConfig (line 2434) | getConfig() {
    method getCachedItemsCount (line 2438) | getCachedItemsCount() {
    method cacheSize (line 2442) | cacheSize() {
    method clearCache (line 2446) | clearCache() {

FILE: dist/src/interfaces/PokeAPIOptions.js
  class PokeAPIOptions (line 1) | class PokeAPIOptions {
    method constructor (line 3) | constructor(config = {}, cache) {

FILE: dist/src/utils/ErrorHandler.js
  function handleError (line 3) | function handleError(error, callback) {

FILE: dist/src/utils/Getter.js
  function getJSON (line 4) | async function getJSON(values, url,

FILE: generator/AddJSDocs.ts
  function addJsDoc (line 24) | function addJsDoc(
  function loadDocumentation (line 63) | async function loadDocumentation(namespace: ModuleDeclaration, docName: ...

FILE: generator/TypesGenerator.ts
  function clearAndUpper (line 20) | function clearAndUpper(text: string) {
  function toPascalCase (line 24) | function toPascalCase(text: string) {
  function generateFinalFile (line 32) | async function generateFinalFile(types: string) {
  function quicktypeMain (line 164) | async function quicktypeMain(jsonSchema: string, basename: string) {

FILE: src/index.ts
  class Pokedex (line 13) | class Pokedex {
    method constructor (line 16) | constructor(options?: PokeAPIOptions) {
    method getResource (line 22) | async getResource(endpoint: string | string[], callback?: (result: any...
    method resource (line 61) | async resource(endpoint: string | string[], callback?: (result: any | ...
    method getBerryByName (line 99) | async getBerryByName(nameOrId: string | number | Array<string | number...
    method getBerryFirmnessByName (line 138) | async getBerryFirmnessByName(nameOrId: string | number | Array<string ...
    method getBerryFlavorByName (line 177) | async getBerryFlavorByName(nameOrId: string | number | Array<string | ...
    method getContestTypeByName (line 216) | async getContestTypeByName(nameOrId: string | number | Array<string | ...
    method getContestEffectById (line 255) | async getContestEffectById(id: number | number[], callback?: ((result:...
    method getSuperContestEffectById (line 294) | async getSuperContestEffectById(id: number | number[], callback?: ((re...
    method getEncounterMethodByName (line 333) | async getEncounterMethodByName(nameOrId: string | number | Array<strin...
    method getEncounterConditionByName (line 372) | async getEncounterConditionByName(nameOrId: string | number | Array<st...
    method getEncounterConditionValueByName (line 411) | async getEncounterConditionValueByName(nameOrId: string | number | Arr...
    method getEvolutionChainById (line 450) | async getEvolutionChainById(id: number | number[], callback?: ((result...
    method getEvolutionTriggerByName (line 489) | async getEvolutionTriggerByName(nameOrId: string | number | Array<stri...
    method getGenerationByName (line 528) | async getGenerationByName(nameOrId: string | number | Array<string | n...
    method getPokedexByName (line 567) | async getPokedexByName(nameOrId: string | number | Array<string | numb...
    method getVersionByName (line 606) | async getVersionByName(nameOrId: string | number | Array<string | numb...
    method getVersionGroupByName (line 645) | async getVersionGroupByName(nameOrId: string | number | Array<string |...
    method getItemByName (line 684) | async getItemByName(nameOrId: string | number | Array<string | number>...
    method getItemAttributeByName (line 723) | async getItemAttributeByName(nameOrId: string | number | Array<string ...
    method getItemCategoryByName (line 762) | async getItemCategoryByName(nameOrId: string | number | Array<string |...
    method getItemFlingEffectByName (line 801) | async getItemFlingEffectByName(nameOrId: string | number | Array<strin...
    method getItemPocketByName (line 840) | async getItemPocketByName(nameOrId: string | number | Array<string | n...
    method getMachineById (line 879) | async getMachineById(id: number | number[], callback?: ((result: PokeA...
    method getMoveByName (line 918) | async getMoveByName(nameOrId: string | number | Array<string | number>...
    method getMoveAilmentByName (line 957) | async getMoveAilmentByName(nameOrId: string | number | Array<string | ...
    method getMoveBattleStyleByName (line 996) | async getMoveBattleStyleByName(nameOrId: string | number | Array<strin...
    method getMoveCategoryByName (line 1035) | async getMoveCategoryByName(nameOrId: string | number | Array<string |...
    method getMoveDamageClassByName (line 1074) | async getMoveDamageClassByName(nameOrId: string | number | Array<strin...
    method getMoveLearnMethodByName (line 1113) | async getMoveLearnMethodByName(nameOrId: string | number | Array<strin...
    method getMoveTargetByName (line 1152) | async getMoveTargetByName(nameOrId: string | number | Array<string | n...
    method getLocationByName (line 1191) | async getLocationByName(nameOrId: string | number | Array<string | num...
    method getLocationAreaByName (line 1230) | async getLocationAreaByName(nameOrId: string | number | Array<string |...
    method getPalParkAreaByName (line 1269) | async getPalParkAreaByName(nameOrId: string | number | Array<string | ...
    method getRegionByName (line 1308) | async getRegionByName(nameOrId: string | number | Array<string | numbe...
    method getAbilityByName (line 1347) | async getAbilityByName(nameOrId: string | number | Array<string | numb...
    method getCharacteristicById (line 1386) | async getCharacteristicById(id: number | number[], callback?: ((result...
    method getEggGroupByName (line 1425) | async getEggGroupByName(nameOrId: string | number | Array<string | num...
    method getGenderByName (line 1464) | async getGenderByName(nameOrId: string | number | Array<string | numbe...
    method getGrowthRateByName (line 1503) | async getGrowthRateByName(nameOrId: string | number | Array<string | n...
    method getNatureByName (line 1542) | async getNatureByName(nameOrId: string | number | Array<string | numbe...
    method getPokeathlonStatByName (line 1581) | async getPokeathlonStatByName(nameOrId: string | number | Array<string...
    method getPokemonByName (line 1620) | async getPokemonByName(nameOrId: string | number | Array<string | numb...
    method getPokemonColorByName (line 1659) | async getPokemonColorByName(nameOrId: string | number | Array<string |...
    method getPokemonFormByName (line 1698) | async getPokemonFormByName(nameOrId: string | number | Array<string | ...
    method getPokemonHabitatByName (line 1737) | async getPokemonHabitatByName(nameOrId: string | number | Array<string...
    method getPokemonShapeByName (line 1776) | async getPokemonShapeByName(nameOrId: string | number | Array<string |...
    method getPokemonSpeciesByName (line 1815) | async getPokemonSpeciesByName(nameOrId: string | number | Array<string...
    method getStatByName (line 1854) | async getStatByName(nameOrId: string | number | Array<string | number>...
    method getTypeByName (line 1893) | async getTypeByName(nameOrId: string | number | Array<string | number>...
    method getLanguageByName (line 1932) | async getLanguageByName(nameOrId: string | number | Array<string | num...
    method getBerriesList (line 1969) | async getBerriesList(interval?: ListEndpointOptions, callback?: (resul...
    method getBerriesFirmnessList (line 1989) | async getBerriesFirmnessList(interval?: ListEndpointOptions, callback?...
    method getBerriesFirmnesssList (line 2010) | async getBerriesFirmnesssList(interval?: ListEndpointOptions, callback...
    method getBerriesFlavorsList (line 2030) | async getBerriesFlavorsList(interval?: ListEndpointOptions, callback?:...
    method getContestTypesList (line 2050) | async getContestTypesList(interval?: ListEndpointOptions, callback?: (...
    method getContestEffectsList (line 2070) | async getContestEffectsList(interval?: ListEndpointOptions, callback?:...
    method getSuperContestEffectsList (line 2090) | async getSuperContestEffectsList(interval?: ListEndpointOptions, callb...
    method getEncounterMethodsList (line 2110) | async getEncounterMethodsList(interval?: ListEndpointOptions, callback...
    method getEncounterConditionsList (line 2130) | async getEncounterConditionsList(interval?: ListEndpointOptions, callb...
    method getEncounterConditionValuesList (line 2150) | async getEncounterConditionValuesList(interval?: ListEndpointOptions, ...
    method getEvolutionChainsList (line 2170) | async getEvolutionChainsList(interval?: ListEndpointOptions, callback?...
    method getEvolutionTriggersList (line 2190) | async getEvolutionTriggersList(interval?: ListEndpointOptions, callbac...
    method getGenerationsList (line 2210) | async getGenerationsList(interval?: ListEndpointOptions, callback?: (r...
    method getPokedexsList (line 2231) | async getPokedexsList(interval?: ListEndpointOptions, callback?: (resu...
    method getPokedexList (line 2251) | async getPokedexList(interval?: ListEndpointOptions, callback?: (resul...
    method getVersionsList (line 2271) | async getVersionsList(interval?: ListEndpointOptions, callback?: (resu...
    method getVersionGroupsList (line 2291) | async getVersionGroupsList(interval?: ListEndpointOptions, callback?: ...
    method getItemsList (line 2311) | async getItemsList(interval?: ListEndpointOptions, callback?: (result:...
    method getItemAttributesList (line 2331) | async getItemAttributesList(interval?: ListEndpointOptions, callback?:...
    method getItemCategoriesList (line 2351) | async getItemCategoriesList(interval?: ListEndpointOptions, callback?:...
    method getItemFlingEffectsList (line 2371) | async getItemFlingEffectsList(interval?: ListEndpointOptions, callback...
    method getItemPocketsList (line 2391) | async getItemPocketsList(interval?: ListEndpointOptions, callback?: (r...
    method getMachinesList (line 2411) | async getMachinesList(interval?: ListEndpointOptions, callback?: (resu...
    method getMovesList (line 2431) | async getMovesList(interval?: ListEndpointOptions, callback?: (result:...
    method getMoveAilmentsList (line 2451) | async getMoveAilmentsList(interval?: ListEndpointOptions, callback?: (...
    method getMoveBattleStylesList (line 2471) | async getMoveBattleStylesList(interval?: ListEndpointOptions, callback...
    method getMoveCategoriesList (line 2491) | async getMoveCategoriesList(interval?: ListEndpointOptions, callback?:...
    method getMoveDamageClassesList (line 2511) | async getMoveDamageClassesList(interval?: ListEndpointOptions, callbac...
    method getMoveLearnMethodsList (line 2531) | async getMoveLearnMethodsList(interval?: ListEndpointOptions, callback...
    method getMoveTargetsList (line 2551) | async getMoveTargetsList(interval?: ListEndpointOptions, callback?: (r...
    method getLocationsList (line 2571) | async getLocationsList(interval?: ListEndpointOptions, callback?: (res...
    method getLocationAreasList (line 2591) | async getLocationAreasList(interval?: ListEndpointOptions, callback?: ...
    method getPalParkAreasList (line 2611) | async getPalParkAreasList(interval?: ListEndpointOptions, callback?: (...
    method getRegionsList (line 2631) | async getRegionsList(interval?: ListEndpointOptions, callback?: (resul...
    method getAbilitiesList (line 2651) | async getAbilitiesList(interval?: ListEndpointOptions, callback?: (res...
    method getCharacteristicsList (line 2671) | async getCharacteristicsList(interval?: ListEndpointOptions, callback?...
    method getEggGroupsList (line 2691) | async getEggGroupsList(interval?: ListEndpointOptions, callback?: (res...
    method getGendersList (line 2711) | async getGendersList(interval?: ListEndpointOptions, callback?: (resul...
    method getGrowthRatesList (line 2731) | async getGrowthRatesList(interval?: ListEndpointOptions, callback?: (r...
    method getNaturesList (line 2751) | async getNaturesList(interval?: ListEndpointOptions, callback?: (resul...
    method getPokeathlonStatsList (line 2771) | async getPokeathlonStatsList(interval?: ListEndpointOptions, callback?...
    method getPokemonsList (line 2791) | async getPokemonsList(interval?: ListEndpointOptions, callback?: (resu...
    method getPokemonColorsList (line 2811) | async getPokemonColorsList(interval?: ListEndpointOptions, callback?: ...
    method getPokemonFormsList (line 2831) | async getPokemonFormsList(interval?: ListEndpointOptions, callback?: (...
    method getPokemonHabitatsList (line 2851) | async getPokemonHabitatsList(interval?: ListEndpointOptions, callback?...
    method getPokemonShapesList (line 2871) | async getPokemonShapesList(interval?: ListEndpointOptions, callback?: ...
    method getPokemonSpeciesList (line 2891) | async getPokemonSpeciesList(interval?: ListEndpointOptions, callback?:...
    method getStatsList (line 2911) | async getStatsList(interval?: ListEndpointOptions, callback?: (result:...
    method getTypesList (line 2931) | async getTypesList(interval?: ListEndpointOptions, callback?: (result:...
    method getLanguagesList (line 2951) | async getLanguagesList(interval?: ListEndpointOptions, callback?: (res...
    method getEndpointsList (line 2971) | async getEndpointsList(interval?: ListEndpointOptions, callback?: (res...
    method getConfig (line 2993) | getConfig() {
    method getCachedItemsCount (line 2998) | getCachedItemsCount() {
    method cacheSize (line 3003) | cacheSize() {
    method clearCache (line 3008) | clearCache() {

FILE: src/interfaces/ListEndpointOptions.d.ts
  type ListEndpointOptions (line 1) | interface ListEndpointOptions {

FILE: src/interfaces/PokeAPIOptions.ts
  class PokeAPIOptions (line 3) | class PokeAPIOptions {
    method constructor (line 43) | constructor(config: PokeAPIOptions = {}, cache: NodeCache) {

FILE: src/utils/ErrorHandler.ts
  function handleError (line 3) | function handleError(error: any, callback?: (result: any, error?: boolea...

FILE: src/utils/Getter.ts
  function getJSON (line 6) | async function getJSON<T>(

FILE: types/index.d.ts
  type APIResource (line 11) | interface APIResource {
  type APIResourceList (line 17) | interface APIResourceList {
  type Description (line 29) | interface Description {
  type Effect (line 37) | interface Effect {
  type Encounter (line 45) | interface Encounter {
  type FlavorText (line 59) | interface FlavorText {
  type GenerationGameIndex (line 68) | interface GenerationGameIndex {
  type EndpointsList (line 76) | interface EndpointsList {
  type MachineVersionDetail (line 128) | interface MachineVersionDetail {
  type Name (line 136) | interface Name {
  type NamedAPIResource (line 144) | interface NamedAPIResource {
  type NamedAPIResourceList (line 152) | interface NamedAPIResourceList {
  type VerboseEffect (line 164) | interface VerboseEffect {
  type VersionEncounterDetail (line 174) | interface VersionEncounterDetail {
  type VersionGameIndex (line 184) | interface VersionGameIndex {
  type VersionGroupFlavorText (line 192) | interface VersionGroupFlavorText {
  type Ability (line 203) | interface Ability {
  type EffectChange (line 225) | interface EffectChange {
  type AbilityPokemon (line 233) | interface AbilityPokemon {
  type Berry (line 244) | interface Berry {
  type Flavor (line 272) | interface Flavor {
  type BerryFirmness (line 279) | interface BerryFirmness {
  type BerryFlavor (line 292) | interface BerryFlavor {
  type BerryElement (line 306) | interface BerryElement {
  type Characteristic (line 313) | interface Characteristic {
  type ContestEffect (line 328) | interface ContestEffect {
  type ContestType (line 343) | interface ContestType {
  type ContestTypeName (line 355) | interface ContestTypeName extends Name {
  type EggGroup (line 360) | interface EggGroup {
  type EncounterCondition (line 373) | interface EncounterCondition {
  type EncounterConditionValue (line 386) | interface EncounterConditionValue {
  type EncounterMethod (line 399) | interface EncounterMethod {
  type EvolutionChain (line 412) | interface EvolutionChain {
  type Chain (line 422) | interface Chain {
  type EvolutionDetail (line 430) | interface EvolutionDetail {
  type EvolutionTrigger (line 471) | interface EvolutionTrigger {
  type Gender (line 484) | interface Gender {
  type PokemonSpeciesDetail (line 496) | interface PokemonSpeciesDetail {
  type Generation (line 503) | interface Generation {
  type GrowthRate (line 526) | interface GrowthRate {
  type Level (line 542) | interface Level {
  type Item (line 549) | interface Item {
  type RarityVersion (line 583) | interface RarityVersion {
  type HeldByPokemon (line 589) | interface HeldByPokemon {
  type ItemSprites (line 595) | interface ItemSprites {
  type ItemAttribute (line 602) | interface ItemAttribute {
  type ItemCategory (line 617) | interface ItemCategory {
  type ItemFlingEffect (line 632) | interface ItemFlingEffect {
  type ItemPocket (line 645) | interface ItemPocket {
  type Language (line 658) | interface Language {
  type Location (line 675) | interface Location {
  type LocationArea (line 692) | interface LocationArea {
  type EncounterMethodRate (line 710) | interface EncounterMethodRate {
  type EncounterMethodRateVersionDetail (line 718) | interface EncounterMethodRateVersionDetail {
  type LocationAreaPokemonEncounter (line 724) | interface LocationAreaPokemonEncounter {
  type Machine (line 733) | interface Machine {
  type Move (line 746) | interface Move {
  type ContestCombos (line 798) | interface ContestCombos {
  type ComboDetail (line 804) | interface ComboDetail {
  type Meta (line 810) | interface Meta {
  type StatChange (line 826) | interface StatChange {
  type MoveAilment (line 833) | interface MoveAilment {
  type MoveBattleStyle (line 846) | interface MoveBattleStyle {
  type MoveCategory (line 857) | interface MoveCategory {
  type MoveDamageClass (line 870) | interface MoveDamageClass {
  type MoveLearnMethod (line 885) | interface MoveLearnMethod {
  type MoveTarget (line 900) | interface MoveTarget {
  type Nature (line 915) | interface Nature {
  type MoveBattleStylePreference (line 937) | interface MoveBattleStylePreference {
  type PokeathlonStatChange (line 947) | interface PokeathlonStatChange {
  type PalParkArea (line 954) | interface PalParkArea {
  type PalParkAreaPokemonEncounter (line 966) | interface PalParkAreaPokemonEncounter {
  type PokeathlonStat (line 974) | interface PokeathlonStat {
  type PokeathlonStatAffectingNatures (line 986) | interface PokeathlonStatAffectingNatures {
  type AffectingNaturesChange (line 992) | interface AffectingNaturesChange {
  type Pokedex (line 999) | interface Pokedex {
  type PokemonEntry (line 1019) | interface PokemonEntry {
  type PokemonEncounter (line 1027) | interface PokemonEncounter {
  type Pokemon (line 1034) | interface Pokemon {
  type PokemonAbility (line 1077) | interface PokemonAbility {
  type Cries (line 1087) | interface Cries {
  type HeldItem (line 1093) | interface HeldItem {
  type MoveElement (line 1099) | interface MoveElement {
  type VersionGroupDetail (line 1105) | interface VersionGroupDetail {
  type PastAbility (line 1112) | interface PastAbility {
  type PastAbilityAbility (line 1118) | interface PastAbilityAbility {
  type PastType (line 1125) | interface PastType {
  type PastTypeType (line 1131) | interface PastTypeType {
  type PokemonSprites (line 1137) | interface PokemonSprites {
  type Other (line 1159) | interface Other {
  type DreamWorld (line 1167) | interface DreamWorld {
  type Home (line 1173) | interface Home {
  type OfficialArtwork (line 1181) | interface OfficialArtwork {
  type Showdown (line 1187) | interface Showdown {
  type SpriteVersions (line 1199) | interface SpriteVersions {
  type GenerationI (line 1211) | interface GenerationI {
  type GenerationISprite (line 1217) | interface GenerationISprite {
  type GenerationIi (line 1227) | interface GenerationIi {
  type GenerationIiSpriteExtra (line 1234) | interface GenerationIiSpriteExtra {
  type GenerationIiSprite (line 1246) | interface GenerationIiSprite {
  type GenerationIii (line 1255) | interface GenerationIii {
  type GenerationIiiSpriteBasic (line 1262) | interface GenerationIiiSpriteBasic {
  type GenerationIiiSprite (line 1268) | interface GenerationIiiSprite {
  type GenerationIv (line 1276) | interface GenerationIv {
  type GenerationIvSprite (line 1283) | interface GenerationIvSprite {
  type GenerationV (line 1296) | interface GenerationV {
  type GenerationVSprite (line 1301) | interface GenerationVSprite {
  type Animated (line 1314) | interface Animated {
  type GenerationVi (line 1326) | interface GenerationVi {
  type GenerationViSprite (line 1332) | interface GenerationViSprite {
  type GenerationVii (line 1339) | interface GenerationVii {
  type GenerationViiIcons (line 1345) | interface GenerationViiIcons {
  type GenerationViiSprite (line 1351) | interface GenerationViiSprite {
  type GenerationViii (line 1359) | interface GenerationViii {
  type GenerationViiiIcons (line 1364) | interface GenerationViiiIcons {
  type StatElement (line 1370) | interface StatElement {
  type PokemonType (line 1377) | interface PokemonType {
  type PokemonColor (line 1386) | interface PokemonColor {
  type PokemonForm (line 1399) | interface PokemonForm {
  type PokemonFormSprites (line 1431) | interface PokemonFormSprites {
  type PokemonFormType (line 1447) | interface PokemonFormType {
  type PokemonHabitat (line 1456) | interface PokemonHabitat {
  type PokemonShape (line 1469) | interface PokemonShape {
  type AwesomeName (line 1483) | interface AwesomeName {
  type PokemonSpecies (line 1492) | interface PokemonSpecies {
  type Genus (line 1550) | interface Genus {
  type PalParkEncounter (line 1558) | interface PalParkEncounter {
  type PokedexNumber (line 1565) | interface PokedexNumber {
  type Variety (line 1571) | interface Variety {
  type Region (line 1578) | interface Region {
  type Stat (line 1597) | interface Stat {
  type AffectingMoves (line 1619) | interface AffectingMoves {
  type AffectingMovesChange (line 1625) | interface AffectingMovesChange {
  type StatAffectingNatures (line 1631) | interface StatAffectingNatures {
  type SuperContestEffect (line 1638) | interface SuperContestEffect {
  type Type (line 1651) | interface Type {
  type DamageRelations (line 1676) | interface DamageRelations {
  type PastDamageRelation (line 1686) | interface PastDamageRelation {
  type TypePokemon (line 1692) | interface TypePokemon {
  type TypeSprites (line 1700) | interface TypeSprites {
  type IconName (line 1711) | interface IconName {
  type IconsGenerationIii (line 1716) | interface IconsGenerationIii {
  type IconsGenerationIv (line 1725) | interface IconsGenerationIv {
  type IconsGenerationIx (line 1732) | interface IconsGenerationIx {
  type IconsGenerationV (line 1737) | interface IconsGenerationV {
  type IconsGenerationVi (line 1743) | interface IconsGenerationVi {
  type IconsGenerationVii (line 1749) | interface IconsGenerationVii {
  type IconsGenerationViii (line 1756) | interface IconsGenerationViii {
  type Version (line 1764) | interface Version {
  type VersionGroup (line 1777) | interface VersionGroup {
  type ListEndpointOptions (line 1798) | interface ListEndpointOptions {
  type PokeAPIOptions (line 1807) | interface PokeAPIOptions {
  class PokeAPI (line 1831) | class PokeAPI {
Condensed preview — 38 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (518K chars).
[
  {
    "path": ".editorconfig",
    "chars": 160,
    "preview": "[*.{js,jsx,ts,tsx,vue}]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_fin"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 2439,
    "preview": "name: Tests\n\non: [push, pull_request]\n\njobs:\n  pnpm:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node"
  },
  {
    "path": ".gitignore",
    "chars": 50,
    "preview": "node_modules/\ndist/generator/\ndist/test/\napi-data/"
  },
  {
    "path": ".npmignore",
    "chars": 72,
    "preview": "node_modules\ntest\n.travis.yml\nwebpack.config.js\ngenerator\ndist/generator"
  },
  {
    "path": ".npmrc",
    "chars": 22,
    "preview": "legacy-peer-deps=true\n"
  },
  {
    "path": "LICENSE",
    "chars": 1083,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2016 Thomas Asadurian\n\nPermission is hereby granted, free of charge, to any person "
  },
  {
    "path": "README.md",
    "chars": 21169,
    "preview": "# pokedex-promise-v2 <a href=\"https://pokeapi.co/api/v2/pokemon/bulbasaur\"><img src='https://raw.githubusercontent.com/P"
  },
  {
    "path": "dist/src/index.js",
    "chars": 119392,
    "preview": "/* eslint-disable */\n/*\n* DO NOT MODIFY, THIS IS AUTO GENERATED\n* Execute `npm run generate` to regenerate\n*/\nimport pMa"
  },
  {
    "path": "dist/src/interfaces/PokeAPIOptions.js",
    "chars": 1051,
    "preview": "class PokeAPIOptions {\n    /* eslint-disable default-param-last */\n    constructor(config = {}, cache) {\n        this.pr"
  },
  {
    "path": "dist/src/utils/Endpoints.js",
    "chars": 2229,
    "preview": "const endpoints = [\n    ['getBerryByName', 'berry'],\n    ['getBerryFirmnessByName', 'berry-firmness'],\n    ['getBerryFla"
  },
  {
    "path": "dist/src/utils/ErrorHandler.js",
    "chars": 254,
    "preview": "/* eslint-disable no-shadow */\n/* eslint-disable no-unused-vars */\nfunction handleError(error, callback) {\n    if (callb"
  },
  {
    "path": "dist/src/utils/Getter.js",
    "chars": 1633,
    "preview": "/* eslint-disable import/no-unresolved */\nimport axios from 'axios';\nimport handleError from './ErrorHandler.js';\nasync "
  },
  {
    "path": "dist/src/utils/RootEndpoints.js",
    "chars": 2554,
    "preview": "const rootEndpoints = [\n    ['getEndpointsList', ''],\n    ['getBerriesList', 'berry/'],\n    ['getBerriesFirmnessList', '"
  },
  {
    "path": "eslint.config.js",
    "chars": 491,
    "preview": "import tseslint from '@typescript-eslint/eslint-plugin';\nimport tsparser from '@typescript-eslint/parser';\n\nexport defau"
  },
  {
    "path": "generator/.eslintrc",
    "chars": 278,
    "preview": "{\n  \"rules\": {\n    \"import/no-extraneous-dependencies\": \"off\",\n    \"import/no-unresolved\": \"off\",\n    \"no-console\": \"off"
  },
  {
    "path": "generator/AddJSDocs.ts",
    "chars": 3735,
    "preview": "import axios from 'axios';\nimport path from 'path';\nimport { InterfaceDeclaration, ModuleDeclaration, Project } from 'ts"
  },
  {
    "path": "generator/Main.ts",
    "chars": 14089,
    "preview": "import fs from 'fs';\nimport path from 'path';\nimport { MethodDeclarationStructure, OptionalKind, Project } from 'ts-morp"
  },
  {
    "path": "generator/TypesGenerator.ts",
    "chars": 8055,
    "preview": "import fs from 'fs';\nimport path from 'path';\nimport directoryTree from 'directory-tree';\nimport { Project, Writers } fr"
  },
  {
    "path": "generator/Utils.ts",
    "chars": 697,
    "preview": "/* eslint-disable no-underscore-dangle */\nimport { fileURLToPath } from 'url';\nimport path, { dirname } from 'path';\n\nex"
  },
  {
    "path": "generator/tsconfig.json",
    "chars": 382,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"es2020\",\n    \"module\": \"es2020\",\n    \"importHelpers\": true,\n    \"moduleResolutio"
  },
  {
    "path": "package.json",
    "chars": 3438,
    "preview": "{\n  \"name\": \"pokedex-promise-v2\",\n  \"type\": \"module\",\n  \"version\": \"4.2.1\",\n  \"description\": \"A library used to get info"
  },
  {
    "path": "src/index.ts",
    "chars": 155390,
    "preview": "/*\n* DO NOT MODIFY, THIS IS AUTO GENERATED\n* Execute `npm run generate` to regenerate\n*/\nimport pMap from \"p-map\";\nimpor"
  },
  {
    "path": "src/interfaces/ListEndpointOptions.d.ts",
    "chars": 270,
    "preview": "interface ListEndpointOptions {\n  /** The offset to be used in the request */\n  offset?: number,\n  /** The limit to be u"
  },
  {
    "path": "src/interfaces/PokeAPIOptions.ts",
    "chars": 1742,
    "preview": "import NodeCache from 'node-cache';\n\nclass PokeAPIOptions {\n  /** The protocol to be used\n   * @default 'https'\n   */\n  "
  },
  {
    "path": "src/utils/Endpoints.ts",
    "chars": 2146,
    "preview": "const endpoints: string[][] = [\n  ['getBerryByName', 'berry'],\n  ['getBerryFirmnessByName', 'berry-firmness'],\n  ['getBe"
  },
  {
    "path": "src/utils/ErrorHandler.ts",
    "chars": 225,
    "preview": " \n \nfunction handleError(error: any, callback?: (result: any, error?: boolean | any) => any) {\n  if (callback) {\n    cal"
  },
  {
    "path": "src/utils/Getter.ts",
    "chars": 1587,
    "preview": "import axios, { AxiosResponse } from 'axios';\n\nimport handleError from './ErrorHandler.js';\nimport PokeAPIOptions from '"
  },
  {
    "path": "src/utils/RootEndpoints.ts",
    "chars": 2453,
    "preview": "const rootEndpoints = [\n  ['getEndpointsList', ''],\n  ['getBerriesList', 'berry/'],\n  ['getBerriesFirmnessList', 'berry-"
  },
  {
    "path": "test/.eslintrc",
    "chars": 127,
    "preview": "{\n  \"rules\": {\n    \"import/no-unresolved\": \"off\",\n    \"no-undef\": \"off\",\n    \"func-names\": \"off\",\n    \"no-console\": \"off"
  },
  {
    "path": "test/Async.spec.ts",
    "chars": 334,
    "preview": "import assert from 'assert';\n\nimport Pokedex from '../src/index.js';\n\nconst P = new Pokedex({\n  protocol: 'https',\n  hos"
  },
  {
    "path": "test/Base.spec.ts",
    "chars": 784,
    "preview": "import chai from 'chai';\nimport chaiThings from 'chai-things';\nimport chaiAsPromised from 'chai-as-promised';\nimport Pok"
  },
  {
    "path": "test/ClearCache.spec.ts",
    "chars": 513,
    "preview": "import assert from 'assert';\n\nimport Pokedex from '../src/index.js';\n\nconst P = new Pokedex();\n\n(async () => {\n  try {\n "
  },
  {
    "path": "test/CommonCalls.spec.ts",
    "chars": 14968,
    "preview": "import chai from 'chai';\nimport chaiThings from 'chai-things';\nimport chaiAsPromised from 'chai-as-promised';\nimport Pok"
  },
  {
    "path": "test/CustomUncommonCalls.spec.ts",
    "chars": 4019,
    "preview": "import chai from 'chai';\nimport chaiThings from 'chai-things';\nimport chaiAsPromised from 'chai-as-promised';\nimport Pok"
  },
  {
    "path": "test/Resource.spec.ts",
    "chars": 2085,
    "preview": "import chai from 'chai';\nimport chaiThings from 'chai-things';\nimport chaiAsPromised from 'chai-as-promised';\nimport Pok"
  },
  {
    "path": "test/RootEndpoints.spec.ts",
    "chars": 14293,
    "preview": "import chai from 'chai';\nimport chaiThings from 'chai-things';\nimport chaiAsPromised from 'chai-as-promised';\nimport Pok"
  },
  {
    "path": "tsconfig.json",
    "chars": 396,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"es2020\",\n    \"module\": \"es2020\",\n    \"moduleResolution\": \"node\",\n    \"skipLibChe"
  },
  {
    "path": "types/index.d.ts",
    "chars": 118758,
    "preview": "/*\n* Type definitions for pokedex-promise-v2 v4.x\n* DO NOT MODIFY, THIS IS AUTO GENERATED\n* Code by: HRKings <https://gi"
  }
]

About this extraction

This page contains the full source code of the PokeAPI/pokedex-promise-v2 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 38 files (491.6 KB), approximately 113.8k tokens, and a symbol index with 382 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!