How to build a simple SDK on TypeScript
Tags: typescript, codenewbie, node
Published: 2020-08-11 15:12:47

Hey guys, it's been a while since I wrote a tutorial but this one is something I'm actually working on, so I decided to share with you what I learned :heart:.

**BTW** we are building a small wrapper for [Pokeapi](https://pokeapi.co/)

# what we will do
1. Start a node project
2. Install our dependencies
3. Setup eslint & prettier
4. Setup our package.json
5. Start coding
6. Setup small project for testing
7. Let's Publish

## Start a node project
So I will assume you at least know how to do this, but if not you have a picture down here:
![npm init](https://dev-to-uploads.s3.amazonaws.com/i/4py6aqyy4vmy4tqd9bij.png)
You just need an empty folder and run the next command on it
```bash
npm init -y
```
Now I did some changes to my package.json (keywords, author, repo and version) you don't need to make this changes, but take a look at them if you will like to.

```json
{
  "name": "pokeapi",
  "version": "0.1.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    
  },
  "keywords": [
    "pokemon",
    "api",
    "sdk",
    "typescript",
    "tutorial"
  ],
  "author": "David M.",
  "license": "GPLv3"
}
```
You will notice scripts is empty :eyes: we will fill it later

## Install our dependencies
Now we will install one of our dev dependencies
```bash
npm install -D typescript
```
great! now we need another file on our folder root, it's called "tsconfig.json" you can copy the one that I used (below here) or you can generate it with the next command.

```bash
./node_modules/.bin/tsc --init
```
If you decided for this approach just make sure to adjust the declaration and outDir options according to the JSON bellow.

Setting the declaration attribute to true ensures that the compiler generates the respective TypeScript definitions files aside of compiling the TypeScript files to JavaScript files. The outDir parameter defines the output directory as the dist folder.

or just use mine ¯\\\_(ツ)\_/¯

```json
{
  "compilerOptions": {
    "target": "ES2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "strict": true, /* Enable all strict type-checking options. */
    "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "skipLibCheck": true, /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
    "declaration": true,
    "outDir": "./dist",
  }
}
```

once we have this setup we will need to add some dependencies (this ones may not apply for your sdk)

```bash
npm install -S axios
```
now we are over with our dependencies... for now :eyes:

## Setup eslint and prettier
### Eslint
I think this part it's actually the shortest so let's start
you will need to run the next command:
```bash
npx eslint --init
```
Now... I recommend the next answers for the eslint init
![Eslint init](https://dev-to-uploads.s3.amazonaws.com/i/s3zjlrudfeb065r5ceef.png)

### Prettier
You need to run the next command
```bash
npm install -D prettier eslint-config-prettier eslint-plugin-prettier
```

After you have all that installed change the content of your `.eslintrc.json` with this
```json
{
    "env": {
        "es6": true,
        "node": true
    },
    "extends": [
        "airbnb-base",
        "prettier/@typescript-eslint",
        "plugin:prettier/recommended"
    ],
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": 11,
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint"
    ],
    "rules": {}
}
```

and add the file `.prettierrc.json` with this inside
```json
{
    "printWidth": 100,
    "tabWidth": 2,
    "singleQuote": true,
    "jsxBracketSameLine": true,
    "trailingComma": "es5"
}
```

## Setup our package.json
now that we finally have all the development setup ready we need to modify a bit our `package.json` so it know it's a TypeScript project
```json
{
  "name": "pokeapi",
  "version": "0.1.0",
  "description": "",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "prepare": "npm run build",
    "build": "tsc"
  },
  "keywords": [
    "pokemon",
    "api",
    "sdk",
    "typescript",
    "tutorial"
  ],
  "author": "David M.",
  "license": "GPLv3",
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^3.9.0",
    "@typescript-eslint/parser": "^3.9.0",
    "eslint": "^7.6.0",
    "eslint-config-airbnb-base": "^14.2.0",
    "eslint-config-prettier": "^6.11.0",
    "eslint-plugin-import": "^2.22.0",
    "eslint-plugin-prettier": "^3.1.4",
    "prettier": "^2.0.5",
    "typescript": "^3.9.7"
  },
  "dependencies": {
    "axios": "^0.19.2"
  }
}
```
If you notice, all that we changed is the scripts and added some settings main and types,
remember if you change your outputdir on `tsconfig.json` change it on your `package.json`.

## Start coding
**FINALLY**
Let's make a new file called index.ts (on our root)
this is where our SDK will leave, we obviously and separate it on different files and import them but my example is short and simple so I will use the same file for all of it.

First we will import everything
```ts
import axios from 'axios';
```
Let's add some variables we will need
```ts
import axios from 'axios';

const API_URL: string = 'https://pokeapi.co/api/v2';
```

perfect! now that we have "all" setup lets start by adding our first sdk method (getPokemonById)

```ts
import axios from 'axios';

const API_URL: string = 'https://pokeapi.co/api/v2';

export function getPokemonById(id: number): Promise<object> {
  return new Promise((resolve, reject) => {
    axios
      .get(`${API_URL}/pokemon/${id}`)
      .then((resp) => {
        resolve(resp.data);
      })
      .catch(reject);
  });
}

export default { getPokemonById };
```
Finally our code should look something like this, notice that we export our function and as an export default we use "all of our functions" I will add another function so we can have a better idea of multiple functions working from the sdk. It should look like this...

```ts
import axios from 'axios';

const API_URL: string = 'https://pokeapi.co/api/v2';

export function getPokemonById(id: number): Promise<object> {
  return new Promise((resolve, reject) => {
    axios
      .get(`${API_URL}/pokemon/${id}`)
      .then((resp) => {
        resolve(resp.data);
      })
      .catch(reject);
  });
}

export function getPokemonTypeById(id: number): Promise<object> {
  return new Promise((resolve, reject) => {
    axios
      .get(`${API_URL}/type/${id}`)
      .then((resp) => {
        resolve(resp.data);
      })
      .catch(reject);
  });
}

export default { getPokemonById, getPokemonTypeById };

```

## Setup small project for testing

Now that we have a really bare bones version of our SDK we will try to use it, but first we should build it!
for simplicity we will make a new node project inside our project like so...

```bash
npm run build
mkdir testing
cd testing
npm init -y
npm install ..
```
now this should make our new project ready to make import our sdk and running it.

my test looked a little like this
```js
const pokeapi = require('pokeapi');

pokeapi.getPokemonById(1).then((pokemon) => {
  console.log(pokemon.name);
});
// it should say "bulbasaur"
```

## Let's Publish
Great to know that you made it until here :heart:
lets start right away!
we will need a new file called `.npmignore` where we will add all the folders we don't want our sdk to bring with itself like our "testing" folder
it should look like this
```txt
testing/
```
and that should be all for your code :heart:
now the last part is to have an account on [Npm](https://www.npmjs.com/) do the next commands

```bash
npm login #do all the steps necessary
npm publish
```

and your sdk should be ready to be installed in any other node projects.

Here's some links that you might want:
[Npm](https://www.npmjs.com/sinepokemonapi)
[Repo](https://github.com/Dmendoza99/pokeapi)

I hope this quick tutorial really helped someone, because I wasn't lucky enough to find one as explicit as this one haha.