Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
MrScopes committed Jan 11, 2021
0 parents commit f41976f
Show file tree
Hide file tree
Showing 41 changed files with 6,442 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
dist/
.env
93 changes: 93 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
![](https://nodei.co/npm/anilist.js.png?downloads=true)\
NPM module for communicating with Anilist.\
Find any bugs or have any suggestions?\
Create an issue on the repo or contact me on Discord @MrScopes#5548

## Table of Contents
- [Documentation](#documentation)
- [Notes](#notes)

## Example
```js
const Client = require('anilist-js');
const AniList = new Client('API TOKEN'); // token is only required for some features

(async () => {

// list the 3 most popular MHA seasons
const search = await AniList.searchMedia({ search: 'My Hero Academia', format: 'TV', perPage: 3, sort: 'POPULARITY_DESC' });
console.log(search.Results.map(result => result.info.title));

// toggle favourite status for naruto (character)
const characters = await AniList.searchCharacters({ search: 'Naruto Uzumaki' });
const naruto = characters.Results[0];
await naruto.favourite(); // this requires an api token

})();
```

## Documentation
Note: `variables` parameters are 100% auto completion compatible.\
These docs are most likely temporary.\
View the [example usage](#example).\
_Italics_ represents authorization required.
- Methods:
- `.getMedia(id)`
- `.searchMedia(variables)`
<br><br>
- `.getCharacter(id)`
- `.searchCharacters(variables)`
<br><br>
- _`.me()`_ -> Currently authorized user
- `.getUser(id)`
- `.searchUsers(variables)`
<br><br>
- `.getStaff(id)`
- `.searchStaff(variables)`
<br><br>
- `.getStudio(id)`
- `.searchStudios(variables)`

- Structures:
- Search Results:
- .Results[\<StructureType>]
- .pageInfo
<br><br>
- `Media >`
- .info
- _.update(variables)_
- _.favourite()_
<br><br>
- `Character >`
- .info
- _.favourite()_
<br><br>
- _`Viewer >`_ represents the current authorized user
- _.info_
- _.update(variables)_
- `User >`
- .info
- _.follow()_
<br><br>
- `Staff >`
- .info
- _.favourite()_
<br><br>
- `Studio >`
- .info
- .favourite()

## Notes:
- This is my first large npm module. So some things might not work 100% as intended.

- The JSON output is massive, so keep the following in mind:
- A lot of data is taken out, for example, in user info: statistics is taken out
- nodes are taken out. use `edges[] > node`
- for `edges[] > node`, only important info is left in like `id`, `title (or name)`

- API Key:
- API Keys are needed for user-specific methods, but you can still get media, characters, etc.
- Get yours @ [https://anilist-token.glitch.me/](https://anilist-token.glitch.me/). This is secure, created by me, and open source.

- Types:
- Types are mainly auto generated, but not every property is 100% supported (this is mainly so the json isn't more massive than it is).
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "anilist.js",
"version": "1.0.0",
"description": "Communicate with the AniList API.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"test": "tsc && node dist/test.js"
},
"keywords": [
"anime",
"anilist",
"typescript"
],
"repository": "https://github.com/MrScopes/anilist.js",
"author": "MrScopes",
"license": "ISC",
"dependencies": {
"node-fetch": "^2.6.1"
},
"devDependencies": {
"@types/node-fetch": "^2.5.7",
"dotenv": "^8.2.0"
}
}
148 changes: 148 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import Utilities from './utilities';
import { CharacterQuery } from './queries/queries/character/CharacterQuery';
import { CharacterSearchQuery } from './queries/queries/character/CharacterSearchQuery';
import { CharacterSearchResults } from './structures/character/CharacterSearchResults';
import { CharacterStructure } from './structures/character/CharacterStructure';
import { MediaQuery } from './queries/queries/media/MediaQuery';
import { MediaSearchQuery } from './queries/queries/media/MediaSearchQuery';
import { MediaSearchResults } from './structures/media/MediaSearchResults';
import { MediaStructure } from './structures/media/MediaStructure';
import { PageCharactersArgs, PageMediaArgs, PageStaffArgs, PageStudiosArgs, PageUsersArgs } from './types/types';
import { UserStructure } from './structures/user/UserStructure';
import { UserSearchResults } from './structures/user/UserSearchResults';
import { UserSearchQuery } from './queries/queries/user/UserSearchQuery';
import { UserQuery } from './queries/queries/user/UserQuery';
import { ViewerQuery } from './queries/queries/user/ViewerQuery';
import { ViewerStructure } from './structures/user/ViewerStructure';
import { StaffStructure } from './structures/staff/StaffStructure';
import { StaffSearchResults } from './structures/staff/StaffSearchResults';
import { StudioStructure } from './structures/studio/StudioStructure';
import { StudioSearchResults } from './structures/studio/StudioSearchResults';
import { StaffQuery } from './queries/queries/staff/StaffQuery';
import { StaffSearchQuery } from './queries/queries/staff/StaffSearchQuery';
import { StudioQuery } from './queries/queries/studio/StudioQuery';
import { StudioSearchQuery } from './queries/queries/studio/StudioSearchQuery';

/** The main anilist.js class. */
class Client {
token?: string;
utilities: Utilities;

/**
* "Logs in" to AniList. Required for some features.
* @param token API token
*/
constructor(token?: string) {
this.utilities = new Utilities();
this.token = token;
}

/**
* Gets the media with the matching ID.
* @param id media id
*/
async getMedia(id: number) {
const json = await this.utilities.APIRequest(MediaQuery, { id }, this);
return new MediaStructure(json, this);
}

/**
* Gets the media with the maching variables.
* @param variables filter variables
* @example
* .searchMedia({ format: 'OVA', includedTags: ['Body Horror'] })
*/
async searchMedia(variables: PageMediaArgs) {
const json = await this.utilities.APIRequest(MediaSearchQuery, variables, this);
return new MediaSearchResults(json, this);
}

/**
* Gets the character with the matching ID.
* @param id character id
*/
async getCharacter(id: number) {
const json = await this.utilities.APIRequest(CharacterQuery, { id }, this);
return new CharacterStructure(json, this);
}

/**
* Gets the characters with the maching variables.
* @param variables filter variables
* @example
* .searchCharacters({ name: 'Naruto' })
*/
async searchCharacters(variables: PageCharactersArgs) {
const json = await this.utilities.APIRequest(CharacterSearchQuery, variables, this);
return new CharacterSearchResults(json, this);
}

/**
* Gets the currently authorized user.\
* This requires you to be logged in.
* @example
* .me().info.id
*/
async me() {
const json = await this.utilities.APIRequest(ViewerQuery, {}, this);
return new ViewerStructure(json, this);
}

/**
* Gets the character with the matching ID.
* @param id character id
*/
async getUser(id: number) {
const json = await this.utilities.APIRequest(UserQuery, { id }, this);
return new UserStructure(json, this);
}

/**
* Gets the characters with the maching variables.
* @param variables filter variables
* @example
* .searchCharacters({ name: 'Naruto' })
*/
async searchUsers(variables: PageUsersArgs) {
const json = await this.utilities.APIRequest(UserSearchQuery, variables, this);
return new UserSearchResults(json, this);
}

/**
* Gets the staff with the matching ID.
* @param id staff id
*/
async getStaff(id: number) {
const json = await this.utilities.APIRequest(StaffQuery, { id }, this);
return new StaffStructure(json, this);
}

/**
* Gets the staff with the matching variables.
* @param variables filter variables
*/
async searchStaff(variables: PageStaffArgs) {
const json = await this.utilities.APIRequest(StaffSearchQuery, variables, this);
return new StaffSearchResults(json, this);
}

/**
* Gets the studio with the matching ID.
* @param id studio id
*/
async getStudio(id: number) {
const json = await this.utilities.APIRequest(StudioQuery, { id }, this);
return new StudioStructure(json, this);
}

/**
* Gets the studios with the matching variables.
* @param variables filter variables
*/
async searchStudios(variables: PageStudiosArgs) {
const json = await this.utilities.APIRequest(StudioSearchQuery, variables, this);
return new StudioSearchResults(json, this);
}
}

export = Client;
15 changes: 15 additions & 0 deletions src/queries/mutations/character/CharacterFavorite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const CharacterFavorite = `
mutation ($id: Int) {
ToggleFavourite(characterId: $id) {
characters {
edges {
node {
id
}
}
}
}
}
`

export { CharacterFavorite };
15 changes: 15 additions & 0 deletions src/queries/mutations/media/AnimeFavourite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const AnimeFavorite = `
mutation ($id: Int) {
ToggleFavourite(animeId: $id) {
anime {
edges {
node {
id
}
}
}
}
}
`

export { AnimeFavorite };
15 changes: 15 additions & 0 deletions src/queries/mutations/media/MangaFavourite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const MangaFavorite = `
mutation ($id: Int) {
ToggleFavourite(mangaId: $id) {
manga {
edges {
node {
id
}
}
}
}
}
`

export { MangaFavorite };
32 changes: 32 additions & 0 deletions src/queries/mutations/media/MediaUpdate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const MediaUpdate = `
mutation ($id: Int, $mediaId: Int, $status: MediaListStatus, $score: Float, $scoreRaw: Int, $progress: Int, $progressVolumes: Int, $repeat: Int, $priority: Int, $private: Boolean, $notes: String, $hiddenFromStatusLists: Boolean, $customLists: [String], $advancedScores: [Float], $startedAt: FuzzyDateInput, $completedAt: FuzzyDateInput) {
SaveMediaListEntry(id: $id, mediaId: $mediaId, status: $status, score: $score, scoreRaw: $scoreRaw, progress: $progress, progressVolumes: $progressVolumes, repeat: $repeat, priority: $priority, private: $private, notes: $notes, hiddenFromStatusLists: $hiddenFromStatusLists, customLists: $customLists, advancedScores: $advancedScores, startedAt: $startedAt, completedAt: $completedAt) {
id
userId
mediaId
status
score
progress
progressVolumes
repeat
priority
private
notes
hiddenFromStatusLists
customLists
advancedScores
startedAt {
year
month
day
}
completedAt {
year
month
day
}
}
}
`

export { MediaUpdate };
15 changes: 15 additions & 0 deletions src/queries/mutations/staff/StaffFavourite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const StaffFavorite = `
mutation ($id: Int) {
ToggleFavourite(staffId: $id) {
staff {
edges {
node {
id
}
}
}
}
}
`

export { StaffFavorite };
15 changes: 15 additions & 0 deletions src/queries/mutations/studio/StudioFavourite.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const StudioFavorite = `
mutation ($id: Int) {
ToggleFavourite(studioId: $id) {
studios {
edges {
node {
id
}
}
}
}
}
`

export { StudioFavorite };
Loading

0 comments on commit f41976f

Please sign in to comment.