├── lib └── Request.js ├── package.json ├── LICENSE ├── readme.md └── jikan-node.js /lib/Request.js: -------------------------------------------------------------------------------- 1 | const fetch = require('cross-fetch') 2 | const URL = require('url').URL 3 | 4 | module.exports = class Request { 5 | constructor(){ 6 | this.baseURL = "https://api.jikan.moe/v3" 7 | } 8 | 9 | async send(args, params) { 10 | var res = await fetch(this.createUrl(args, params)) 11 | var data = await res.json() 12 | if (res.status !== 200) throw `Response: ${res.status}` 13 | else return data 14 | } 15 | 16 | createUrl (args, params) { 17 | const url = new URL(this.baseURL) 18 | url.pathname += `/${args.filter(a => a).join("/")}` 19 | for (let p in params) { 20 | url.searchParams.set(p, params[p]) 21 | } 22 | return url.href 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jikan-node", 3 | "version": "1.2.1", 4 | "description": "Wrapper for the unofficial MAL api, Jikan", 5 | "main": "jikan-node.js", 6 | "directories": { 7 | "lib": "lib" 8 | }, 9 | "dependencies": { 10 | "cross-fetch": "^3.0.2" 11 | }, 12 | "devDependencies": {}, 13 | "scripts": { 14 | "test": "echo \"Error: no test specified\" && exit 1" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/xy137/jikan-node.git" 19 | }, 20 | "keywords": [ 21 | "node", 22 | "nodejs", 23 | "javascript", 24 | "js", 25 | "jikan", 26 | "mal", 27 | "api" 28 | ], 29 | "author": "xy137", 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/xy137/jikan-node/issues" 33 | }, 34 | "homepage": "https://github.com/xy137/jikan-node#readme" 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 xy137 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Jikan-node 2 | 3 | Jikan-node is a node (and javascript) wrapper for the unofficial MAL api, Jikan 4 | 5 | Link to API: https://jikan.docs.apiary.io/ 6 | 7 | Link to genre IDs : https://jikan.docs.apiary.io/#reference/0/search 8 | 9 | ## Installation 10 | 11 | `npm install jikan-node --save` 12 | 13 | ## Features 14 | 15 | * User lookup 16 | * Anime lookup 17 | * Manga lookup 18 | * Person lookup 19 | * Character lookup 20 | * Search 21 | * Season lookup 22 | * Schedule lookup 23 | * Top 24 | * Genre lookup 25 | * Producer lookup 26 | * Magazine lookup 27 | * Club lookup 28 | 29 | ## Usage 30 | 31 | ```javascript 32 | const Jikan = require('jikan-node'); 33 | const mal = new Jikan(); 34 | ``` 35 | 36 | ### Example 37 | 38 | The code below will find every Nisemonogatari (https://myanimelist.net/anime/11597/Nisemonogatari) episode on the first page, since there is only one page for episodes it will return that single page. The ids for shows are in the url and page number is optional. 39 | ```javascript 40 | mal.findAnime('11597', 'episodes', 1) 41 | .then(info => console.log(info)) 42 | .catch(err => console.log(err)); 43 | ``` -------------------------------------------------------------------------------- /jikan-node.js: -------------------------------------------------------------------------------- 1 | const Request = require('./lib/Request') 2 | 3 | module.exports = class JikanNode { 4 | 5 | constructor() { 6 | this.request = new Request 7 | } 8 | 9 | /** 10 | * 11 | * @param {integer} id anime ID 12 | * @param {string} request character_staff, episodes, news, pictures, videos, stats, forum, moreinfo, reviews, recommendations, userupdates 13 | * @param {integer} page can be used to select pages when needed 14 | */ 15 | async findAnime(id, request, page) { 16 | return await this.request.send(['anime', id, request, page]) 17 | } 18 | 19 | /** 20 | * 21 | * @param {integer} id manga ID 22 | * @param {string} request characters, news, pictures, stats, forum, moreinfo, reviews, recommendations, userupdates 23 | * @param {integer} page can be used to select pages when needed 24 | */ 25 | async findManga(id, request, page) { 26 | return await this.request.send(['manga', id, request, page]) 27 | } 28 | 29 | /** 30 | * 31 | * @param {integer} id person ID 32 | * @param {string} request pictures 33 | */ 34 | async findPerson(id, request) { 35 | return await this.request.send(['person', id, request]) 36 | } 37 | 38 | /** 39 | * 40 | * @param {integer} id character ID 41 | * @param {string} request pictures 42 | */ 43 | async findCharacter(id, request) { 44 | return await this.request.send(['character', id, request]) 45 | } 46 | 47 | /** 48 | * 49 | * @param {string} type anime/manga/people ect 50 | * @param {string} title title 51 | * @param {object} param page, type, status, rated, genre, score, start_date, end_date, genre_exclude | ex. {page: 2, score: 7} 52 | * 53 | */ 54 | async search(type, title, param) { 55 | const params = {'q': title, ...param} 56 | return await this.request.send(['search', type], params) 57 | 58 | } 59 | 60 | /** 61 | * 62 | * @param {string} season summer, fall, winter, spring 63 | * @param {integer} year ex. 2019 64 | */ 65 | async findSeason(season, year) { 66 | return await this.request.send(['season', year, season]) 67 | } 68 | 69 | /** 70 | * 71 | * @param {string} day monday, tuesday, wednesday, ect.., other, unknown. pass nothing will 72 | * return the schedule for all days of the week 73 | */ 74 | async findSchedule(day) { 75 | return await this.request.send(['schedule', day]) 76 | } 77 | 78 | /** 79 | * 80 | * @param {string} type anime, manga, people, characters 81 | * @param {integer} page optional page number 82 | * @param {string} subtype returns a filtered list 83 | */ 84 | async findTop(type, page, subtype) { 85 | return await this.request.send(['top', type, page, subtype]) 86 | } 87 | 88 | /** 89 | * 90 | * @param {string} type anime or manga 91 | * @param {integer} id genre id 92 | * @param {integer} page page number 93 | */ 94 | async findGenre(type, id, page) { 95 | return await this.request.send(['genre', type, id, page]) 96 | } 97 | 98 | /** 99 | * 100 | * @param {integer} id producer id 101 | * @param {integer} page page number 102 | */ 103 | async findProducer(id, page) { 104 | return await this.request.send(['producer', id, page]) 105 | } 106 | 107 | /** 108 | * 109 | * @param {integer} id magazine id 110 | * @param {integer} page page number 111 | */ 112 | async findMagazine(id, page) { 113 | return await this.request.send(['producer', id, page]) 114 | } 115 | 116 | /** 117 | * 118 | * @param {string} username username 119 | * @param {string} request profile, history, friends, animelist, mangalist 120 | * @param {string} data watching, ptw, onhold, ect 121 | * @param {Object} param page sort search 122 | */ 123 | async findUser(username, request, data, param) { 124 | return await this.request.send(['user', username, request, data], param) 125 | } 126 | 127 | /** 128 | * 129 | * @param {integer} id id of club 130 | * @param {string} request members 131 | */ 132 | async findClub(id, request) { 133 | return await this.request.send(['club', id, request ]) 134 | } 135 | } --------------------------------------------------------------------------------