Skip to content

Commit

Permalink
[HS] Initial release of @blizzard-api/hs
Browse files Browse the repository at this point in the history
  • Loading branch information
Pewtro committed Oct 6, 2024
1 parent dddd542 commit 2e59a69
Show file tree
Hide file tree
Showing 23 changed files with 839 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-pumas-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@blizzard-api/hs': minor
---

Initial release of @blizzard-api/hs
13 changes: 1 addition & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,10 @@ Currently available game-specific packages are:

- `@blizzard-api/classic-wow`
- `@blizzard-api/d3`
- `@blizzard-api/hs`
- `@blizzard-api/sc2`
- `@blizzard-api/wow`

Additionally planned packages are:

- `@blizzard-api/hs`

The core package gives you access to helper functions such as `getBlizzardApi` which will quickly get you the hostname and locales for a specific region.

The game package will let you access paths, namespaces, parameters and more for each endpoint. This can imported like so:
Expand Down Expand Up @@ -67,11 +64,3 @@ console.log(response.data);
## Authentication

Please refer to the [battle.net documentation](https://develop.battle.net/documentation/guides/getting-started) for guides on how to obtain Blizzard API credentials.

## TODO

This list is generally prioritized but no promises that things will be addressed in this order.

- Migrate the client away from axios to native fetch
- Add a package for the following games/flavours
- Hearthstone
7 changes: 2 additions & 5 deletions packages/client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ This package provides a client that is meant to be used together with one or mor

Currently available packages are:

- `@blizzard-api/d3`
- `@blizzard-api/wow`
- `@blizzard-api/classic-wow`

Planned packages are:

- `@blizzard-api/d3`
- `@blizzard-api/hs`
- `@blizzard-api/sc2`
- `@blizzard-api/wow`

## Installation

Expand Down
1 change: 1 addition & 0 deletions packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@blizzard-api/classic-wow": "workspace:*",
"@blizzard-api/core": "workspace:*",
"@blizzard-api/d3": "workspace:*",
"@blizzard-api/hs": "workspace:*",
"@blizzard-api/sc2": "workspace:*",
"@blizzard-api/wow": "workspace:*"
},
Expand Down
49 changes: 49 additions & 0 deletions packages/client/src/tests/hs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { hs } from '@blizzard-api/hs';
import { describe, it } from 'vitest';
import { environment } from '../../../../environment';
import { createBlizzardApiClient } from '../client/create-client';

describe.concurrent('smoketest some hs api responses', async () => {
const client = await createBlizzardApiClient({
key: environment.blizzardClientId,
origin: 'eu',
secret: environment.blizzardClientSecret,
});

it('should be able to search for a card back', async ({ expect }) => {
const response = await client.sendRequest(hs.cardBackSearch({ locale: 'en_GB' }));
expect(response.data).toBeDefined();
});

it('should be able to fetch a card back', async ({ expect }) => {
const response = await client.sendRequest(hs.fetchOneCardBack('1', 'en_GB'));
expect(response.data).toBeDefined();
});

it('should be able to search for a card', async ({ expect }) => {
const response = await client.sendRequest(hs.cardSearch({ locale: 'en_GB', textFilter: 'fireball' }));
expect(response.data).toBeDefined();
});

it('should be able to fetch a card', async ({ expect }) => {
const response = await client.sendRequest(hs.fetchOneCard('52119-arch-villain-rafaam'));
expect(response.data).toBeDefined();
});

it('should be able to fetch a deck', async ({ expect }) => {
const response = await client.sendRequest(
hs.getDeck({ code: 'AAECAQcG+wyd8AKS+AKggAOblAPanQMMS6IE/web8wLR9QKD+wKe+wKz/AL1gAOXlAOalAOSnwMA' }),
);
expect(response.data).toBeDefined();
});

it('should be able to fetch all metadata', async ({ expect }) => {
const response = await client.sendRequest(hs.allMetadata());
expect(response.data).toBeDefined();
});

it('should be able to fetch specific metadata', async ({ expect }) => {
const response = await client.sendRequest(hs.specificMetadata('classes'));
expect(response.data).toBeDefined();
});
});
1 change: 1 addition & 0 deletions packages/hs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# @blizzard-api/hs
75 changes: 75 additions & 0 deletions packages/hs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# @blizzard-api/hs

This package aims to make it easier for you to integrate with the Blizzard Battle.net API, specifically for Diablo 3.

## Installation

```sh
npm i @blizzard-api/core @blizzard-api/hs
```

## Usage

You can get paths, namespaces, parameters and more for a specific endpoint by calling it from the `hs` export.

```ts
import { hs } from "@blizzard-api/hs"
//or
import hs from "@blizzard-api/hs"

const season = hs.allMetadata(123);
^ Resource<AllMetadataResponse>
```

If you don't want to use the exported hs object, you can also access the functions directly:

```ts
import { allMetadata } from "@blizzard-api/hs"

const seasonI = season(123);
^ Resource<AllMetadataResponse>
```

### Types

If you need the response types, they are also exported with "Response" appended, so to get the response type from the above code, you can import it like this:

```ts
import type { SeasonResponse } from '@blizzard-api/hs';
```

If you simply want to use the existing object, you can use the helper, `ExtractResourceType`, from `@blizzard-api/core` like so:

```ts
import { hs } from "@blizzard-api/hs"

const season = hs.allMetadata();
^ Resource<AllMetadataResponse>

type AllMetadataResponse = ExtractResourceType<typeof season>;
```

## Notes on Types

The types are manually created from using the Blizzard API documentation, and are as accurate as possible with smoke testing each endpoint. However, no-one is perfect so there is likely to be some discrepancies. If you encounter any issues with the types from this package, please open an issue or a pull request.

### Client

While this package is made to function on it's own, it performs even better when combined with `@blizzard-api/client` where you can easily request data combining the two libraries.

```ts
import { createBlizzardApiClient } from '@blizzard-api/client';
import { hs } from '@blizzard-api/hs';

const client = await createBlizzardApiClient({
key: 'environment.blizzardClientId',
secret: 'environment.blizzardClientSecret',
origin: 'eu',
});

//Response will automatically be typed with the appropriate values
const response = await client.sendRequest(hs.allMetadata());

console.log(response.data);
^ typeof AllMetadataResponse
```
51 changes: 51 additions & 0 deletions packages/hs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "@blizzard-api/hs",
"version": "0.0.0",
"license": "MIT",
"author": "Putro",
"description": "A series of helpers to interact with the Hearthstone Blizzard API",
"repository": "https://github.com/Pewtro/blizzard-api/tree/main/packages/hs",
"type": "module",
"engines": {
"node": "^18.18 || ^20.9 || ^21.1 || ^22"
},
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
},
"files": [
"dist"
],
"keywords": [
"blizzard",
"battlenet",
"battle.net",
"bnet",
"api",
"hs",
"hearthstone"
],
"dependencies": {},
"peerDependencies": {
"@blizzard-api/core": "1.2.1"
},
"devDependencies": {
"@blizzard-api/core": "workspace:*"
},
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"test": "vitest run",
"test:coverage": "pnpm test -- --coverage",
"test:watch": "vitest watch"
}
}
7 changes: 7 additions & 0 deletions packages/hs/src/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type SortDirection = 'asc' | 'desc';

type SortOptions = 'attack' | 'class' | 'dataAdded' | 'groupByClass' | 'health' | 'manaCost' | 'name';

export type SearchSortOption = `${SortOptions}:${SortDirection}`;

export type GameMode = 'arena' | 'battlegrounds' | 'classic' | 'constructed' | 'duels' | 'mercenaries' | 'standard';
39 changes: 39 additions & 0 deletions packages/hs/src/card-backs/card-backs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { Locales } from '@blizzard-api/core';
import { describe, expect, it } from 'vitest';
import { cardBackSearch, fetchOneCardBack } from './card-backs';
import type { CardBackSearchParameters } from './types';

describe('cardBackSearch', () => {
it('should return the correct resource object for card back search', () => {
const options: CardBackSearchParameters = { locale: 'en_US', page: 1 };
const result = cardBackSearch(options);

expect(result).toEqual({
parameters: options,
path: 'hearthstone/cardbacks',
});
});
});

describe('fetchOneCardBack', () => {
it('should return the correct resource object for fetching one card back with locale', () => {
const id = '12345';
const locale: Locales = 'en_US';
const result = fetchOneCardBack(id, locale);

expect(result).toEqual({
parameters: { locale },
path: `hearthstone/cardbacks/${id}`,
});
});

it('should return the correct resource object for fetching one card back without locale', () => {
const id = '12345';
const result = fetchOneCardBack(id);

expect(result).toEqual({
parameters: { locale: undefined },
path: `hearthstone/cardbacks/${id}`,
});
});
});
21 changes: 21 additions & 0 deletions packages/hs/src/card-backs/card-backs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Locales, Resource } from '@blizzard-api/core';
import type { CardBackSearchParameters, CardBackSearchResponse, SingleCardBackSearchResponse } from './types';

export function cardBackSearch(
options: CardBackSearchParameters,
): Resource<CardBackSearchResponse, CardBackSearchParameters> {
return {
parameters: options,
path: 'hearthstone/cardbacks',
};
}

export function fetchOneCardBack(
id: string,
locale?: Locales,
): Resource<SingleCardBackSearchResponse, { locale?: Locales }> {
return {
parameters: { locale },
path: `hearthstone/cardbacks/${id}`,
};
}
40 changes: 40 additions & 0 deletions packages/hs/src/card-backs/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type { Locales } from '@blizzard-api/core';
import type { SearchSortOption } from '../base';

export interface CardBackSearchResponse {
cardBacks: Array<SingleCardBackSearchResponse>;
cardCount: number;
page: number;
pageCount: number;
}

export interface SingleCardBackSearchResponse {
id: number;
image: string;
name: Record<Locales, string> | string;
slug: string;
sortCategory: number;
text: Record<Locales, string> | string;
}

export interface CardBackSearchParameters {
cardBackCategory?:
| 'achieve'
| 'base'
| 'blizzard'
| 'esports'
| 'events'
| 'fireside'
| 'game_license'
| 'golden'
| 'heroes'
| 'legend'
| 'pre_purchase'
| 'promotion'
| 'season';
locale?: Locales;
page?: number;
pageSize?: number;
sort?: SearchSortOption;
textFilter?: string;
}
Loading

0 comments on commit 2e59a69

Please sign in to comment.