Skip to content
This repository has been archived by the owner on Nov 6, 2021. It is now read-only.

Commit

Permalink
feat(*): restructure repo
Browse files Browse the repository at this point in the history
repo files have been moved around a lot

BREAKING CHANGE: The repo files have been moved around a lot. This probably won't impact
you too much, but if you were importing from a specific path (not the root of
require('nintendo-switch-eshop')) then you'll have to change your imports.
  • Loading branch information
favna committed Oct 31, 2020
1 parent 1697ec2 commit 59ead46
Show file tree
Hide file tree
Showing 21 changed files with 558 additions and 493 deletions.
2 changes: 2 additions & 0 deletions __tests__/jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ jest.setTimeout(1000 * 60);

// Retry failed twice just in case Tessarect still fails
jest.retryTimes(2);

export default undefined;
2 changes: 1 addition & 1 deletion __tests__/testUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { GameEU, GameJP, GameUS } from '../src/interfaces';
import type { GameEU, GameJP, GameUS } from '../src';

export const JAPANESE_GAME: GameJP = {
LinkURL: '123456789123456789',
Expand Down
4 changes: 2 additions & 2 deletions __tests__/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"rootDir": ".",
"noEmit": true,
"rootDir": ".",
"noEmit": true,
"incremental": false
},
"include": ["."],
Expand Down
26 changes: 22 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
export * from './constants';
export * from './interfaces';
export * from './nintendo-switch-eshop';
export { getGamesAmerica as default } from './nintendo-switch-eshop';
export { getGamesAmerica as default, getGamesAmerica } from './lib/getGames/getGamesAmerica';
export { getGamesEurope } from './lib/getGames/getGamesEurope';
export { getGamesJapan } from './lib/getGames/getGamesJapan';
export { getActiveShops } from './lib/getShops/getActiveShops';
export { getShopsAmerica } from './lib/getShops/getShopsAmerica';
export { getShopsAsia } from './lib/getShops/getShopsAsia';
export { getShopsEurope } from './lib/getShops/getShopsEurope';
export { getPrices } from './lib/other/getPrices';
export { getShopsByCountryCodes } from './lib/other/getShopByCountryCode';
export { parseGameCode } from './lib/other/parseGameCode';
export { parseNSUID } from './lib/other/parseNSUID';
export * from './lib/utils/constants';
export type {
EShop,
EURequestOptions,
GameEU,
GameJP,
GameUS,
PriceResponse,
QueriedGameUS
} from './lib/utils/interfaces';
export { EshopError } from './lib/utils/utils';
142 changes: 142 additions & 0 deletions src/lib/getGames/getGamesAmerica.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import fetch from 'node-fetch';
import { stringify } from 'querystring';
import {
US_ALGOLIA_HEADERS,
US_AVAILABILITY_FILTER,
US_ESRB_RATINGS_FILTERS,
US_FACETS,
US_GAME_LIST_LIMIT,
US_GET_GAMES_URL,
US_INDEX_TITLE_ASC,
US_INDEX_TITLE_DES,
US_PLATFORM_FACET_FILTER
} from '../utils/constants';
import type { AlgoliaResponse, GameUS } from '../utils/interfaces';
import { arrayRemoveDuplicates, EshopError } from '../utils/utils';

/**
* Fetches all games on american e-shops
*
* @remarks
* Currently ONLY returns all games in the e-shop
*
* @returns Promise containing all the games
*/
export const getGamesAmerica = async (): Promise<GameUS[]> => {
const limit = US_GAME_LIST_LIMIT;
const page = 0;

const body = {
body: JSON.stringify({
requests: [
{
indexName: US_INDEX_TITLE_ASC,
params: stringify({
query: '',
hitsPerPage: limit,
page: page,
analytics: false,
facets: JSON.stringify(US_FACETS),
facetFilters: `[["${US_ESRB_RATINGS_FILTERS.everyone}"],["${US_PLATFORM_FACET_FILTER}"]]`
})
},
{
indexName: US_INDEX_TITLE_DES,
params: stringify({
query: '',
hitsPerPage: limit,
page: page,
analytics: false,
facets: JSON.stringify(US_FACETS),
facetFilters: `[["${US_ESRB_RATINGS_FILTERS.everyone}"],["${US_PLATFORM_FACET_FILTER}"]]`
})
},
{
indexName: US_INDEX_TITLE_ASC,
params: stringify({
query: '',
hitsPerPage: limit,
page: page,
analytics: false,
facets: JSON.stringify(US_FACETS),
facetFilters: `[["${US_ESRB_RATINGS_FILTERS.everyone10}"],["${US_PLATFORM_FACET_FILTER}"]]`
})
},
{
indexName: US_INDEX_TITLE_DES,
params: stringify({
query: '',
hitsPerPage: limit,
page: page,
analytics: false,
facets: JSON.stringify(US_FACETS),
facetFilters: `[["${US_ESRB_RATINGS_FILTERS.everyone10}"],["${US_PLATFORM_FACET_FILTER}"]]`
})
},
{
indexName: US_INDEX_TITLE_ASC,
params: stringify({
query: '',
hitsPerPage: limit,
page: page,
analytics: false,
facets: JSON.stringify(US_FACETS),
facetFilters: `[["${US_ESRB_RATINGS_FILTERS.teen}"],["${US_PLATFORM_FACET_FILTER}"]]`
})
},
{
indexName: US_INDEX_TITLE_DES,
params: stringify({
query: '',
hitsPerPage: limit,
page: page,
analytics: false,
facets: JSON.stringify(US_FACETS),
facetFilters: `[["${US_ESRB_RATINGS_FILTERS.teen}"],["${US_PLATFORM_FACET_FILTER}"]]`
})
},
{
indexName: US_INDEX_TITLE_ASC,
params: stringify({
query: '',
hitsPerPage: limit,
page: page,
analytics: false,
facets: JSON.stringify(US_FACETS),
facetFilters: `[["${US_ESRB_RATINGS_FILTERS.mature}"],["${US_PLATFORM_FACET_FILTER}"]]`
})
},
{
indexName: US_INDEX_TITLE_ASC,
params: stringify({
query: '',
hitsPerPage: limit,
page: page,
analytics: false,
facets: JSON.stringify(US_FACETS),
facetFilters: `[["${US_AVAILABILITY_FILTER}"],["${US_PLATFORM_FACET_FILTER}"]]`
})
}
]
}),
method: 'POST',
headers: US_ALGOLIA_HEADERS
};

try {
const allGamesResponse = await fetch(US_GET_GAMES_URL, body);
if (!allGamesResponse.ok) throw new Error('US_games_request_failed');
const gamesResponse: AlgoliaResponse = await allGamesResponse.json();

let allGames: any[] | PromiseLike<GameUS[]> = [];
for (const results of gamesResponse.results) {
allGames = allGames.concat(results.hits);
}

allGames = arrayRemoveDuplicates(allGames, 'slug');
return allGames;
} catch (err) {
if (/(?:US_games_request_failed)/i.test(err.toString())) throw new EshopError('Fetching of US Games failed');
throw err;
}
};
39 changes: 39 additions & 0 deletions src/lib/getGames/getGamesEurope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import fetch from 'node-fetch';
import { stringify } from 'querystring';
import { EU_DEFAULT_LOCALE, EU_GAME_LIST_LIMIT, EU_GET_GAMES_OPTIONS, EU_GET_GAMES_URL } from '../utils/constants';
import type { EURequestOptions, GameEU } from '../utils/interfaces';
import { EshopError } from '../utils/utils';

/**
* Fetches all games on the European, Australian or New Zealand eShops
*
* @remarks
* Games from Australia / New Zealand can be limited. They are included only as much as that Nintendo assigns them properly to the PAL region
*
* @param options - Request options to pass to the eShop request {@link EURequestOptions | See EURequestOptions for details}
* @returns Promise containing all requested EU/PAL games
*/
export const getGamesEurope = async (
options: EURequestOptions = { limit: EU_GAME_LIST_LIMIT, locale: EU_DEFAULT_LOCALE }
): Promise<GameEU[]> => {
if (!options.limit) options.limit = EU_GAME_LIST_LIMIT;
if (!options.locale) options.locale = EU_DEFAULT_LOCALE;

try {
const gamesEU = await fetch(
`${EU_GET_GAMES_URL.replace('{locale}', options.locale)}?${stringify({
rows: options.limit,
...EU_GET_GAMES_OPTIONS
})}`
);

if (!gamesEU.ok) throw new Error('EU_games_request_failed');

const gamesData = await gamesEU.json();

return gamesData.response.docs as GameEU[];
} catch (err) {
if (/(?:EU_games_request_failed)/i.test(err.toString())) throw new EshopError('Fetching of EU Games failed');
throw err;
}
};
27 changes: 27 additions & 0 deletions src/lib/getGames/getGamesJapan.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { parse as xml2json } from 'fast-xml-parser';
import fetch from 'node-fetch';
import { JP_GET_GAMES_URL } from '../utils/constants';
import type { GameJP } from '../utils/interfaces';
import { EshopError } from '../utils/utils';

/**
* Fetches all games on japanese eShops
*
* @returns Promise containing all the games
*/
export const getGamesJapan = async (): Promise<GameJP[]> => {
try {
const gamesJP = await fetch(JP_GET_GAMES_URL);

if (!gamesJP.ok) throw new Error('JP_games_request_failed');

const parsedGamesJP = xml2json(await gamesJP.text());

const allGamesJP: GameJP[] = parsedGamesJP.TitleInfoList.TitleInfo;

return allGamesJP;
} catch (err) {
if (/(?:JP_games_request_failed)/i.test(err.toString())) throw new EshopError('Fetching of JP Games failed');
throw err;
}
};
24 changes: 24 additions & 0 deletions src/lib/getShops/getActiveShops.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { EShop } from '../utils/interfaces';
import { getShopsAmerica } from './getShopsAmerica';
import { getShopsAsia } from './getShopsAsia';
import { getShopsEurope } from './getShopsEurope';

/**
* Gets all active eShops.
*
* @remarks
* This method will launch several requests at nintendo web services, so don't abuse it.
*
* @returns A list of shop objects with country code, name and default currency.
*/
export const getActiveShops = async (): Promise<EShop[]> => {
try {
const shopsAmerica = await getShopsAmerica();
const shopsAsia = await getShopsAsia();
const shopsEurope = await getShopsEurope();

return shopsAmerica.concat(shopsAsia, shopsEurope);
} catch (err) {
throw new Error(err);
}
};
20 changes: 20 additions & 0 deletions src/lib/getShops/getShopsAmerica.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { regions } from 'country-data';
import { getShopsByCountryCodes } from '../other/getShopByCountryCode';
import { Region, US_GAME_CHECK_CODE } from '../utils/constants';
import type { EShop } from '../utils/interfaces';

/**
* Gets all active eShops on American countries.
*
* @remarks
* This method will launch several requests at nintendo web services, so don't abuse it.
*
* @returns A list of shop objects with country code, name and default currency.
*/
export const getShopsAmerica = async (): Promise<EShop[]> => {
return getShopsByCountryCodes(
regions.southAmerica.countries.concat(regions.centralAfrica.countries, regions.northernAmerica.countries),
US_GAME_CHECK_CODE,
Region.AMERICAS
);
};
25 changes: 25 additions & 0 deletions src/lib/getShops/getShopsAsia.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { regions } from 'country-data';
import { getShopsByCountryCodes } from '../other/getShopByCountryCode';
import { JP_GAME_CHECK_CODE, Region } from '../utils/constants';
import type { EShop } from '../utils/interfaces';

/**
* Gets all active eShops on Asian countries
*
* @remarks
* This method will launch several requests at nintendo web services, so don't abuse it.
*
* @returns A list of shop objects with country code, name and default currency.
*/
export const getShopsAsia = async (): Promise<EShop[]> => {
return getShopsByCountryCodes(
regions.southernAsia.countries.concat(
regions.southernAsia.countries,
regions.southeastAsia.countries,
regions.eastAsia.countries,
regions.westernAsia.countries
),
JP_GAME_CHECK_CODE,
Region.ASIA
);
};
26 changes: 26 additions & 0 deletions src/lib/getShops/getShopsEurope.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { regions } from 'country-data';
import { getShopsByCountryCodes } from '../other/getShopByCountryCode';
import { EU_GAME_CHECK_CODE, Region } from '../utils/constants';
import type { EShop } from '../utils/interfaces';

/**
* Gets all active eShops on European countries.
*
* @remarks
* This method will launch several requests at nintendo web services, so don't abuse it.
*
* @returns A list of shop objects with country code, name and default currency.
*/
export const getShopsEurope = async (): Promise<EShop[]> => {
return getShopsByCountryCodes(
regions.northernEurope.countries.concat(
regions.southernEurope.countries,
regions.easternEurope.countries,
regions.westernEurope.countries,
regions.australia.countries,
regions.southernAfrica.countries
),
EU_GAME_CHECK_CODE,
Region.EUROPE
);
};
Loading

0 comments on commit 59ead46

Please sign in to comment.