Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ejnshtein/nyaasi

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ejnshtein/nyaasi - npm Package Compare versions

Comparing version 2.2.3 to 3.0.1

dist/lib/cookie.d.ts

30

dist/Agent.d.ts

@@ -1,27 +0,13 @@

import { RequestOptions, RequestResult } from '@ejnshtein/smol-request';
import { AgentOptions, Cookie, NyaaApiRequestResult, NyaaRequestOptions } from '../types';
import { RequestResult, ResponseType, ResponseTypeMap } from 'smol-request';
import { AgentOptions, NyaaRequestOptions } from '../types/agent';
export declare class Agent {
sessionId?: string;
persistentId?: string;
host: string;
apiHost: string;
_cookies: Cookie[];
sessionId?: string;
constructor({ host, apiHost }?: AgentOptions);
get cookies(): string[];
setCookies(cookies: Cookie[]): void;
getCookies(): string[];
login(username: string, password: string, options?: RequestOptions): Promise<boolean>;
static login(username: string, password: string, options?: RequestOptions & {
baseUrl: string;
}): Promise<Cookie[]>;
_onDeleteSession(): Promise<{
result: string;
}>;
loginWithSession(path: string): Promise<boolean>;
checkLogin(): Promise<boolean>;
saveSession(path: string): Promise<boolean>;
static saveSession(path: string, cookies: string[]): Promise<boolean>;
call(url?: string, options?: {}): Promise<string>;
callApi<T>(url?: string, options?: {}): Promise<NyaaApiRequestResult<T>>;
static call(url: string, options?: NyaaRequestOptions): Promise<RequestResult>;
static callApi<T>(url: string, options?: NyaaRequestOptions): Promise<NyaaApiRequestResult<T>>;
call<K, T extends ResponseType = 'text'>(url?: string, options?: NyaaRequestOptions<T>): Promise<NonNullable<ResponseTypeMap<K>[T]>>;
callApi<T>(url?: string, options?: NyaaRequestOptions<'json'>): Promise<T>;
static call<K, T extends ResponseType = 'text'>(url: string, options?: NyaaRequestOptions<T>): Promise<RequestResult<NonNullable<ResponseTypeMap<K>[T]>>>;
static callApi<T>(url: string, options?: NyaaRequestOptions<'json'>): Promise<T>;
}

@@ -16,35 +16,7 @@ "use strict";

exports.Agent = void 0;
const smol_request_1 = __importDefault(require("@ejnshtein/smol-request"));
const deepmerge_1 = __importDefault(require("deepmerge"));
const cheerio_1 = __importDefault(require("cheerio"));
const smol_request_1 = require("smol-request");
const fs_1 = __importDefault(require("fs"));
const Scraper_1 = require("./Scraper");
const querystring_1 = require("querystring");
const { version: packageVersion } = JSON.parse(fs_1.default.readFileSync('./package.json', 'utf-8'));
const parseCookies = (cookies) => cookies.map((cookie) => cookie.split('; ').reduce((cookie, property) => {
switch (true) {
case property.toLowerCase().includes('domain'): {
return Object.assign(Object.assign({}, cookie), { domain: property.split('=').pop() });
}
case property.toLowerCase().includes('expires'): {
return Object.assign(Object.assign({}, cookie), { expires: new Date(property.split('=').pop()) });
}
case property.toLowerCase().includes('httponly'): {
return Object.assign(Object.assign({}, cookie), { httponly: true });
}
case property.includes('='): {
return property.split('=').map((el, i) => {
if (i === 0) {
return el.toLowerCase();
}
return el;
});
}
}
return cookie;
}, {}));
const cookiesToString = (cookies) => cookies.map((cookie) => {
const [name] = Object.keys(cookie).filter((key) => !['domain', 'httponly', 'expires', 'path'].includes(key));
return `${name}=${cookie[name]}`;
});
const path_1 = __importDefault(require("path"));
const deepmerge_1 = require("./lib/deepmerge");
const pkg = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '..', 'package.json'), 'utf-8'));
class Agent {

@@ -55,115 +27,7 @@ constructor({ host = 'https://nyaa.si', apiHost = 'https://nyaa.si/api' } = {}) {

}
get cookies() {
return cookiesToString(this._cookies);
}
setCookies(cookies) {
this._cookies = cookies
.reduce((cookies, cookie) => {
const [name] = Object.entries(cookie).pop();
if (cookies.some((cookie) => typeof cookie[name] === 'string')) {
const i = cookies.findIndex((cookie) => cookie[name]);
cookies[i] = cookie;
}
else {
cookies.push(cookie);
}
return cookies;
}, this._cookies || [])
.filter((cookie) => {
if (!cookie.expires) {
return true;
}
return (cookie.expires.getTime() !== 0 ||
cookie.expires.getTime() > Date.now());
});
}
getCookies() {
return cookiesToString(this._cookies);
}
login(username, password, options) {
return __awaiter(this, void 0, void 0, function* () {
const cookies = yield Agent.login(username, password, Object.assign({ baseUrl: this.host }, options));
this.setCookies(cookies);
return this.checkLogin();
});
}
static login(username, password, options) {
return __awaiter(this, void 0, void 0, function* () {
if (!username || !password) {
throw new Error('Not enough login info.');
}
const payload = {
username: username,
password: password
};
const { data: tmpData, headers: tmpHeaders } = yield smol_request_1.default(`${options.baseUrl || 'https://nyaa.si'}/login`);
payload.csrf_token = Scraper_1.getCSRFToken(tmpData);
const tmpCookies = parseCookies(tmpHeaders['set-cookie']);
const { headers, data } = yield smol_request_1.default(`${options.baseUrl || 'https://nyaa.si'}/login`, {
method: 'POST',
headers: {
'User-Agent': `nyaa-api/${packageVersion}`,
'Content-Type': 'application/x-www-form-urlencoded',
Cookie: cookiesToString(tmpCookies).join('; ')
}
}, querystring_1.stringify(payload));
const cookies = parseCookies(headers['set-cookie']);
if (!cookies.some((cookie) => cookie.session)) {
const errorText = cheerio_1.default.load(data)('div').text();
if (errorText) {
throw new Error(errorText);
}
throw new Error('Failed to retrieve session id.');
}
return cookies;
});
}
_onDeleteSession() {
return __awaiter(this, void 0, void 0, function* () {
this.sessionId = null;
yield this.call('/logout');
return { result: 'logout' };
});
}
loginWithSession(path) {
return __awaiter(this, void 0, void 0, function* () {
const file = yield fs_1.default.promises.readFile(path, 'utf8');
const cookies = file.split('\n');
this.setCookies(parseCookies(cookies));
const isLogin = this.checkLogin();
return isLogin;
});
}
checkLogin() {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.call('profile');
const isLogin = Scraper_1.parseProfile(result);
return Boolean(isLogin);
});
}
saveSession(path) {
return __awaiter(this, void 0, void 0, function* () {
return Agent.saveSession(path, this.cookies);
});
}
static saveSession(path, cookies) {
return __awaiter(this, void 0, void 0, function* () {
yield fs_1.default.promises.writeFile(path, cookies.join('\n'), 'utf8');
return true;
});
}
call(url = '', options = {}) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield Agent.call(url, deepmerge_1.default.all([
{
baseUrl: this.host,
headers: {
Cookie: this.cookies.join('; ')
}
},
options
]));
if (result.headers['set-cookie']) {
this.setCookies(parseCookies(result.headers['set-cookie']));
}
const result = yield Agent.call(url, deepmerge_1.deepmerge({
baseUrl: this.host
}, options));
return result.data;

@@ -175,5 +39,2 @@ });

const result = yield Agent.callApi(url, Object.assign({ baseUrl: this.apiHost, responseType: 'json' }, options));
if (result.status === 'error') {
throw new Error(result.message);
}
return result;

@@ -185,15 +46,8 @@ });

const finalUrl = `${options.baseUrl || 'https://nyaa.si'}${!(url.startsWith('/') && options.baseUrl.endsWith('/')) && '/'}${url}`;
const finalOptions = deepmerge_1.default.all([
{
method: 'GET',
headers: {
'User-Agent': `nyaa-api/${packageVersion}`
}
},
options
]);
const result = yield smol_request_1.default(finalUrl, finalOptions);
if (result.data.errors) {
throw new Error(result.data.errors[0]);
}
const result = yield smol_request_1.request(finalUrl, deepmerge_1.deepmerge({
method: 'GET',
headers: {
'User-Agent': `nyaa-api/${pkg.version}`
}
}, options));
return result;

@@ -204,4 +58,9 @@ });

return __awaiter(this, void 0, void 0, function* () {
const result = yield Agent.call(`api${!url.startsWith('/') && '/'}${url}`, Object.assign({ responseType: 'json' }, options));
return result;
const { data: response } = yield Agent.call(url, deepmerge_1.deepmerge({
baseUrl: 'https://nyaa.si/api'
}, options, { responseType: 'json' }));
if (response.status === 'error') {
throw new Error(response.message);
}
return response.data;
});

@@ -208,0 +67,0 @@ }

@@ -5,2 +5,1 @@ export * from './Agent';

export * as Scraper from './Scraper';
export * from '../types/index';

@@ -30,2 +30,1 @@ "use strict";

exports.Scraper = __importStar(require("./Scraper"));
__exportStar(require("../types/index"), exports);

@@ -1,4 +0,4 @@

import { AgentOptions, GetTorrentOptions, NyaaApiRequestResult, NyaaRequestOptions, SearchOptions } from '../types';
import { AgentOptions, GetTorrentOptions, NyaaRequestOptions, SearchQuery } from '../types/agent';
import { Agent } from './Agent';
import { Profile, SearchResult, ViewTorrent } from '../types/nyaa';
import { SearchResult, ViewTorrent } from '../types/nyaa';
export declare class Nyaa {

@@ -8,10 +8,6 @@ options: AgentOptions;

constructor(options?: AgentOptions);
getMe(): Promise<Profile>;
search(query: string, options?: SearchOptions, params?: NyaaRequestOptions): Promise<SearchResult>;
static search(query: string, options?: SearchOptions, params?: NyaaRequestOptions): Promise<SearchResult>;
getTorrent(id: number, options?: GetTorrentOptions): Promise<NyaaApiRequestResult<ViewTorrent>>;
static getTorrent(id: number, options?: GetTorrentOptions, params?: NyaaRequestOptions): Promise<ViewTorrent>;
search(query: string | SearchQuery, options?: NyaaRequestOptions<'text'>): Promise<SearchResult>;
static search(query: string | SearchQuery, options?: NyaaRequestOptions<'text'>): Promise<SearchResult>;
getTorrentAnonymous(id: number, options?: GetTorrentOptions, params?: {}): Promise<ViewTorrent>;
static getTorrentAnonymous(id: number, options?: GetTorrentOptions, params?: NyaaRequestOptions): Promise<ViewTorrent>;
static getTorrentAnonymous(id: number, args?: GetTorrentOptions, options?: NyaaRequestOptions<'text'>): Promise<ViewTorrent>;
}
export default Nyaa;

@@ -11,10 +11,8 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Nyaa = void 0;
const deepmerge_1 = __importDefault(require("deepmerge"));
const Scraper_1 = require("./Scraper");
const Agent_1 = require("./Agent");
const deepmerge_1 = require("./lib/deepmerge");
const get_params_1 = require("./lib/get-params");
const DefaultOptions = {

@@ -25,64 +23,47 @@ host: 'https://nyaa.si',

class Nyaa {
constructor(options) {
this.options = Object.assign({}, DefaultOptions, options);
constructor(options = {}) {
this.options = deepmerge_1.deepmerge(DefaultOptions, options);
this.agent = new Agent_1.Agent(this.options);
}
getMe() {
search(query, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.agent.call('profile');
return Scraper_1.parseProfile(result);
});
}
search(query, options = { filter: 0, category: '0_0' }, params = {}) {
return __awaiter(this, void 0, void 0, function* () {
const search = {
q: query,
f: (typeof options.filter !== 'undefined' && options.filter) || 0,
c: (typeof options.filter !== 'undefined' && options.category) || '0_0'
};
const result = yield this.agent.call('', deepmerge_1.default.all([
{
params: search
},
params
]));
const searchParams = get_params_1.getParams(query);
const result = yield this.agent.call('', deepmerge_1.deepmerge(options, {
params: searchParams
}));
return Scraper_1.parseSearch(result, this.options.host);
});
}
static search(query, options = { filter: 0, category: '0_0' }, params = {}) {
static search(query, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
const search = {
q: query,
f: (typeof options.filter !== 'undefined' && options.filter) || 0,
c: (typeof options.filter !== 'undefined' && options.category) || '0_0'
};
const result = yield Agent_1.Agent.call('', deepmerge_1.default.all([
{
params: search
},
params
]));
return Scraper_1.parseSearch(params.baseUrl || 'https://nyaa.si', result.data);
const searchParams = get_params_1.getParams(query);
const result = yield Agent_1.Agent.call('', deepmerge_1.deepmerge(options, {
params: searchParams
}));
return Scraper_1.parseSearch(result.data, options.baseUrl || 'https://nyaa.si');
});
}
getTorrent(id, options = { withComments: false }) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield this.agent.callApi(`info/${id}`);
if (options.withComments) {
const comments = yield this.agent.call(`view/${id}`);
result.data.comments = Scraper_1.parseComments(comments);
}
return result;
});
}
static getTorrent(id, options = { withComments: false }, params = {}) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield Agent_1.Agent.callApi(`info/${id}`, params);
if (options.withComments) {
const comments = yield Agent_1.Agent.call(`view/${id}`, params);
result.data.comments = Scraper_1.parseComments(comments.data);
}
return result.data;
});
}
// async getTorrent(
// id: number,
// options: GetTorrentOptions = { withComments: false }
// ): Promise<ViewTorrent> {
// const result = await this.agent.callApi<ViewTorrent>(`info/${id}`)
// if (options.withComments) {
// const comments = await this.agent.call(`view/${id}`)
// result.comments = parseComments(comments)
// }
// return result
// }
// static async getTorrent(
// id: number,
// options: GetTorrentOptions = { withComments: false },
// params: NyaaRequestOptions<'json'> = {}
// ): Promise<ViewTorrent> {
// const result = await Agent.callApi<ViewTorrent>(`info/${id}`, params)
// if (options.withComments) {
// const comments = await Agent.call(`view/${id}`, params)
// result.comments = parseComments(comments.data as string)
// }
// return result
// }
getTorrentAnonymous(id, options = { withComments: false }, params = {}) {

@@ -93,7 +74,7 @@ return __awaiter(this, void 0, void 0, function* () {

}
static getTorrentAnonymous(id, options = { withComments: false }, params = {}) {
static getTorrentAnonymous(id, args = { withComments: false }, options = {}) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield Agent_1.Agent.call(`view/${id}`, params);
const parsed = Scraper_1.parseTorrent(id, params.baseUrl, result.data);
if (options.withComments) {
const result = yield Agent_1.Agent.call(`view/${id}`, options);
const parsed = Scraper_1.parseTorrent(id, result.data);
if (args.withComments) {
parsed.comments = Scraper_1.parseComments(result.data);

@@ -106,2 +87,1 @@ }

exports.Nyaa = Nyaa;
exports.default = Nyaa;

@@ -1,4 +0,4 @@

import RssParser from 'rss-parser';
import { RSSFile } from '../types/nyaa';
export declare class NyaaRss {
static get(): Promise<RssParser.Output>;
static get(): Promise<RSSFile[]>;
}

@@ -17,2 +17,3 @@ "use strict";

const rss_parser_1 = __importDefault(require("rss-parser"));
const html_entities_1 = require("html-entities");
const parser = new rss_parser_1.default({

@@ -30,4 +31,6 @@ customFields: {

'nyaa:remake',
'nyaa:comments',
'description',
'guid'
'guid',
'title'
]

@@ -40,6 +43,20 @@ }

const data = yield parser.parseURL('https://nyaa.si/?page=rss');
data.items.forEach((el) => {
el.id = Number.parseInt(el.guid.split('/').pop());
});
return data;
const rssFiles = data.items.map((el) => ({
id: Number.parseInt(el.guid.split('/').pop()),
title: html_entities_1.decode(el.title),
guid: el.guid,
description: el.description,
pubDate: new Date(el.pubDate),
seeders: parseInt(el['nyaa:seeders']),
leechers: parseInt(el['nyaa:leechers']),
downloads: parseInt(el['nyaa:downloads']),
infoHash: el['nyaa:infoHash'],
categoryId: el['nyaa:categoryId'],
category: el['nyaa:category'],
size: el['nyaa:size'],
comments: parseInt(el['nyaa:comments']),
trusted: el['nyaa:trusted'],
remake: el['nyaa:remake']
}));
return rssFiles;
});

@@ -46,0 +63,0 @@ }

@@ -1,7 +0,5 @@

import { Comment, Entry, Profile, SearchResult, ViewTorrent } from '../types/nyaa';
export declare const getCSRFToken: (html: string) => string;
export declare const parseProfile: (html: string) => Profile;
import { Comment, Entry, SearchResult, ViewTorrent } from '../types/nyaa';
export declare const parseComments: (html: string) => Comment[];
export declare const parseSearch: (html: string, host?: string) => SearchResult;
export declare const parseTorrent: (id: number, html: string, host?: string) => ViewTorrent;
export declare const parseTorrent: (id: number, html: string) => ViewTorrent;
export declare function getEntry(entry: string): Entry;

@@ -6,27 +6,36 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getEntry = exports.parseTorrent = exports.parseSearch = exports.parseComments = exports.parseProfile = exports.getCSRFToken = void 0;
exports.getEntry = exports.parseTorrent = exports.parseSearch = exports.parseComments = void 0;
const url_1 = require("url");
const cheerio_1 = __importDefault(require("cheerio"));
const bytes_iec_1 = __importDefault(require("bytes-iec"));
const url_1 = require("url");
exports.getCSRFToken = (html) => {
const selector = cheerio_1.default.load(html);
return selector('#csrf_token').attr('value');
};
exports.parseProfile = (html) => {
const selector = cheerio_1.default.load(html);
if (selector('title').text().toLowerCase().includes('redirecting')) {
return null;
}
else {
const profile = {
id: Number.parseInt(selector('body > div > div.row > div.col-sm-10 > dl > dd:nth-child(2)').text()),
username: selector('body > div > h2 > .text-default').text(),
avatar: selector('body > div > div.row > div.col-sm-2 > img').attr('src'),
class: selector('body > div > div.row > div.col-sm-10 > dl > dd:nth-child(4)').text(),
created_at: new Date(selector('body > div > div.row > div.col-sm-10 > dl > dd:nth-child(6)').text())
};
return profile;
}
};
exports.parseComments = (html) => {
// export const getCSRFToken = (html: string): string => {
// const selector = cheerio.load(html)
// return selector('#csrf_token').attr('value')
// }
// export const parseProfile = (html: string): Profile => {
// const selector = cheerio.load(html)
// if (selector('title').text().toLowerCase().includes('redirecting')) {
// return null
// } else {
// const profile = {
// id: Number.parseInt(
// selector(
// 'body > div > div.row > div.col-sm-10 > dl > dd:nth-child(2)'
// ).text()
// ),
// username: selector('body > div > h2 > .text-default').text(),
// avatar: selector('body > div > div.row > div.col-sm-2 > img').attr('src'),
// class: selector(
// 'body > div > div.row > div.col-sm-10 > dl > dd:nth-child(4)'
// ).text(),
// created_at: new Date(
// selector(
// 'body > div > div.row > div.col-sm-10 > dl > dd:nth-child(6)'
// ).text()
// )
// }
// return profile
// }
// }
const parseComments = (html) => {
const select = cheerio_1.default.load(html);

@@ -51,66 +60,145 @@ return select('#collapse-comments > div.panel')

};
exports.parseSearch = (html, host = 'https://nyaa.si') => {
const page = cheerio_1.default.load(html);
const table = page('body > div.container > div.table-responsive > table > tbody');
const files = table
.children('tr')
.map((i, el) => {
const select = cheerio_1.default.load(el);
exports.parseComments = parseComments;
const parseSearch = (html, host = 'https://nyaa.si') => {
const content = cheerio_1.default.load(html);
const parseSearch = (i, el) => {
const tagList = el.childNodes.filter((n) => n.type === 'tag');
const file_size = tagList
.find((tag, i) => tag.name === 'td' && i === 3)
.children.find((tag) => tag.type === 'text')
.data.trim();
return {
id: Number.parseInt(select('td:nth-child(2) > a:last-of-type')
.attr('href')
.split('/')
id: parseInt(tagList
.find((tag, i) => tag.name === 'td' && i === 1)
.children.find((tag) => tag.name === 'a')
.attribs.href.split('/')
.pop()),
category: {
label: select('td:nth-child(1) > a').attr('title'),
code: new url_1.URL(select('td:nth-child(1) > a').attr('href'), host).searchParams.get('c')
label: tagList
.find((tag) => tag.name === 'td')
.children.find((tag) => tag.name === 'a').attribs.title,
code: new url_1.URL(host +
tagList
.find((tag) => tag.name === 'td')
.children.find((tag) => tag.name === 'a').attribs.href).searchParams.get('c')
},
name: select('td:nth-child(2) > a:last-of-type').text().trim(),
name: tagList
.find((tag, i) => tag.name === 'td' && i === 1)
.children.find((tag) => tag.name === 'a' &&
(!tag.attribs.class || !tag.attribs.class.includes('comments')))
.attribs.title.trim(),
links: {
page: select('td:nth-child(2) > a:last-of-type').attr('href'),
file: select('td:nth-child(3) > a').attr('href'),
magnet: select('td:nth-child(3) > a:last-of-type').attr('href')
page: tagList
.find((tag, i) => tag.name === 'td' && i === 1)
.children.find((tag) => tag.name === 'a').attribs.href,
file: tagList
.find((tag, i) => tag.name === 'td' && i === 2)
.children.find((tag) => tag.name === 'a').attribs.href,
magnet: tagList
.find((tag, i) => tag.name === 'td' && i === 2)
.children.find((tag) => tag.name === 'a' &&
tag.attribs.href &&
tag.attribs.href.startsWith('magnet')).attribs.href
},
file_size: select('td:nth-child(4)').text(),
file_size_bytes: bytes_iec_1.default.parse(select('td:nth-child(4)').text()),
timestamp: Number.parseInt(select('td:nth-child(5)').attr('data-timestamp')),
file_size,
file_size_bytes: bytes_iec_1.default.parse(file_size),
stats: {
downloaded: Number.parseInt(select('td:nth-child(8)').text()),
seeders: Number.parseInt(select('td:nth-child(6)').text()),
leechers: Number.parseInt(select('td:nth-child(7)').text())
downloaded: parseInt(tagList
.find((tag, i) => tag.name === 'td' && i === 7)
.children.find((tag) => tag.type === 'text')
.data.trim()),
seeders: parseInt(tagList
.find((tag, i) => tag.name === 'td' && i === 5)
.children.find((tag) => tag.type === 'text')
.data.trim()),
leechers: parseInt(tagList
.find((tag, i) => tag.name === 'td' && i === 6)
.children.find((tag) => tag.type === 'text')
.data.trim())
},
timestamp: parseInt(tagList.find((tag, i) => tag.name === 'td' && i === 4).attribs['data-timestamp']),
entry: getEntry(el.attribs.class)
};
})
.get();
const current_page = Number.parseInt(page('body > div.container > div.center > nav > ul').html()
? new url_1.URL(page('body > div.container > div.center > nav > ul > li.active > a').attr('href'), host).searchParams.get('p')
: page('body > div.container > div.center > ul > li.active').text()) || 1;
const last_page = Number.parseInt(page('body > div.container > div.center > nav > ul').html()
? new url_1.URL(page('body > div.container > div.center > nav > ul > li:last-of-type')
};
const current_page = Number.parseInt(content('body > div.container > div.center > nav > ul').html()
? new url_1.URL(content('body > div.container > div.center > nav > ul > li.active > a').attr('href'), host).searchParams.get('p')
: content('body > div.container > div.center > ul > li.active').text()) || 1;
const last_page = Number.parseInt(content('body > div.container > div.center > nav > ul').html()
? new url_1.URL(content('body > div.container > div.center > nav > ul > li:last-of-type')
.prev()
.children('a')
.attr('href'), host).searchParams.get('p')
: new url_1.URL(page('body > div.container > div.center > ul > li.next')
: new url_1.URL(content('body > div.container > div.center > ul > li.next')
.prev()
.children('a')
.attr('href'), host).searchParams.get('p')) || 1;
return {
const result = {
current_page,
last_page,
files
torrents: content('body > div.container > div.table-responsive > table > tbody')
.children('tr')
.map(parseSearch)
.get()
};
return result;
// // const table = page(
// // 'body > div.container > div.table-responsive > table > tbody'
// // )
// const files = table
// .children('tr')
// .map((i, el) => {
// const select = cheerio(el)
// return {
// id: Number.parseInt(
// select('td:nth-child(2) > a:last-of-type')
// .attr('href')
// .split('/')
// .pop()
// ),
// category: {
// label: select('td:nth-child(1) > a').attr('title'),
// code: new URL(
// select('td:nth-child(1) > a').attr('href'),
// host
// ).searchParams.get('c')
// },
// name: select('td:nth-child(2) > a:last-of-type').text().trim(),
// links: {
// page: select('td:nth-child(2) > a:last-of-type').attr('href'),
// file: select('td:nth-child(3) > a').attr('href'),
// magnet: select('td:nth-child(3) > a:last-of-type').attr('href')
// },
// file_size: select('td:nth-child(4)').text(),
// file_size_bytes: bytes.parse(select('td:nth-child(4)').text()),
// timestamp: Number.parseInt(
// select('td:nth-child(5)').attr('data-timestamp')
// ),
// stats: {
// downloaded: Number.parseInt(select('td:nth-child(8)').text()),
// seeders: Number.parseInt(select('td:nth-child(6)').text()),
// leechers: Number.parseInt(select('td:nth-child(7)').text())
// },
// entry: getEntry(el.attribs.class)
// }
// })
// .get()
// return {
// current_page,
// last_page,
// files
// }
};
exports.parseTorrent = (id, html, host = 'https://nyaa.si') => {
const select = cheerio_1.default.load(html);
select('.servers-cost-money1').remove();
const entryMatch = select('body > div.container > div:first-of-type').attr('class');
exports.parseSearch = parseSearch;
const parseTorrent = (id, html) => {
const content = cheerio_1.default.load(html);
content('.servers-cost-money1').remove();
const entryMatch = content('body > div.container > div:first-of-type').attr('class');
return {
id: id,
name: select('body > div.container > div.panel:first-of-type > div.panel-heading > h3')
name: content('body > div.container > div.panel:first-of-type > div.panel-heading > h3')
.text()
.trim(),
file_size: select('body > div.container > div.panel > div.panel-body > div:nth-child(4) > div:nth-child(2)').html(),
file_size_bytes: bytes_iec_1.default.parse(select('body > div.container > div.panel > div.panel-body > div:nth-child(4) > div:nth-child(2)').html()),
category: select('body > div.container > div.panel > div.panel-body > div:nth-child(1) > div:nth-child(2)')
file_size: content('body > div.container > div.panel > div.panel-body > div:nth-child(4) > div:nth-child(2)').html(),
file_size_bytes: bytes_iec_1.default.parse(content('body > div.container > div.panel > div.panel-body > div:nth-child(4) > div:nth-child(2)').html()),
category: content('body > div.container > div.panel > div.panel-body > div:nth-child(1) > div:nth-child(2)')
.children('a')

@@ -124,12 +212,10 @@ .map((i, el) => ({

links: {
torrent: host +
select('body > div.container > div.panel > div:last-of-type > a:first-of-type').attr('href'),
magnet: select('body > div.container > div.panel > div:last-of-type > a:last-of-type').attr('href')
torrent: content('body > div.container > div.panel > div:last-of-type > a:first-of-type').attr('href'),
magnet: content('body > div.container > div.panel > div:last-of-type > a:last-of-type').attr('href')
},
timestamp: Number.parseInt(select('body > div.container > div.panel > div.panel-body > div:nth-child(1) > div:nth-child(4)').attr('data-timestamp')) * 1000,
submitter: select('body > div.container > div.panel > div.panel-body > div:nth-child(2) > div:nth-child(2) > a').html()
timestamp: Number.parseInt(content('body > div.container > div.panel > div.panel-body > div:nth-child(1) > div:nth-child(4)').attr('data-timestamp')) * 1000,
submitter: content('body > div.container > div.panel > div.panel-body > div:nth-child(2) > div:nth-child(2) > a').html()
? {
name: select('body > div.container > div.panel > div.panel-body > div:nth-child(2) > div:nth-child(2) > a').html(),
link: host +
select('body > div.container > div.panel > div.panel-body > div:nth-child(2) > div:nth-child(2) > a').attr('href')
name: content('body > div.container > div.panel > div.panel-body > div:nth-child(2) > div:nth-child(2) > a').html(),
link: content('body > div.container > div.panel > div.panel-body > div:nth-child(2) > div:nth-child(2) > a').attr('href')
}

@@ -140,12 +226,13 @@ : {

},
description: select('#torrent-description').html(),
info: select('body > div.container > div.panel > div.panel-body > div:nth-child(3) > div:nth-child(2) a').attr('href') || 'No information',
info_hash: select('body > div.container > div.panel > div.panel-body > div:nth-child(5) > div.col-md-5 > kbd').html(),
description: content('#torrent-description').html(),
info: content('body > div.container > div.panel > div.panel-body > div:nth-child(3) > div:nth-child(2) a').attr('href') || 'No information',
info_hash: content('body > div.container > div.panel > div.panel-body > div:nth-child(5) > div.col-md-5 > kbd').html(),
stats: {
seeders: Number.parseInt(select('body > div.container > div.panel > div.panel-body > div:nth-child(2) > div:nth-child(4) > span').html()),
leechers: Number.parseInt(select('body > div.container > div.panel > div.panel-body > div:nth-child(3) > div:nth-child(4) > span').html()),
downloaded: Number.parseInt(select('body > div.container > div.panel > div.panel-body > div:nth-child(4) > div:nth-child(4)').html())
seeders: Number.parseInt(content('body > div.container > div.panel > div.panel-body > div:nth-child(2) > div:nth-child(4) > span').html()),
leechers: Number.parseInt(content('body > div.container > div.panel > div.panel-body > div:nth-child(3) > div:nth-child(4) > span').html()),
downloaded: Number.parseInt(content('body > div.container > div.panel > div.panel-body > div:nth-child(4) > div:nth-child(4)').html())
}
};
};
exports.parseTorrent = parseTorrent;
function getEntry(entry) {

@@ -152,0 +239,0 @@ switch (entry) {

{
"name": "@ejnshtein/nyaasi",
"version": "2.2.3",
"version": "3.0.1",
"description": "Nyaa.si api wrapper for Node written in Typescript",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"types": "./types/index.d.ts",
"scripts": {
"build-ts": "tsc",
"lint": "eslint ./src --ext .ts"
"build": "tsc",
"lint": "eslint ./src --ignore-pattern *.test.*",
"lint:fix": "eslint ./src --ignore-pattern *.test.* --fix",
"test": "jest --config jest.json",
"pretest": "npm run build",
"pb": "np",
"build:docs": "typedoc",
"deploy": "npm run build && npm run build:docs && gh-pages -t -d docs -b gh-pages"
},

@@ -16,4 +22,4 @@ "keywords": [

"files": [
"dist/**/*",
"types/**/*"
"dist",
"types"
],

@@ -30,31 +36,34 @@ "type": "commonjs",

"dependencies": {
"@ejnshtein/smol-request": "^1.1.5",
"bytes-iec": "^3.1.0",
"cheerio": "^1.0.0-rc.3",
"deepmerge": "^4.2.2",
"rss-parser": "^3.9.0"
"bytes-iec": "^3.1.1",
"cheerio": "^1.0.0-rc.5",
"html-entities": "^2.0.2",
"rss-parser": "^3.10.0",
"smol-request": "^2.1.1"
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/preset-typescript": "^7.12.1",
"@types/cheerio": "^0.22.22",
"@types/eslint": "^7.2.4",
"@types/node": "^14.14.6",
"@types/eslint": "^7.2.6",
"@types/node": "^14.14.9",
"@typescript-eslint/eslint-plugin": "^4.6.0",
"@typescript-eslint/parser": "^4.6.0",
"babel-plugin-add-import-extension": "^1.4.3",
"eslint": "^7.12.1",
"eslint-config-prettier": "^6.15.0",
"eslint-config-standard": "^16.0.1",
"domelementtype": "^2.1.0",
"dotenv": "^8.2.0",
"eslint": "^7.17.0",
"eslint-config-prettier": "^7.1.0",
"eslint-config-standard": "^16.0.2",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.2",
"husky": "^4.3.0",
"module-alias": "^2.2.2",
"prettier": "^2.1.2",
"standard": "^16.0.1",
"typescript": "^4.0.5"
"eslint-plugin-standard": "^5.0.0",
"husky": "^4.3.7",
"jest": "^26.6.3",
"np": "^7.2.0",
"prettier": "^2.2.1",
"standard": "^16.0.3",
"ts-jest": "^26.4.4",
"typedoc": "^0.19.2",
"typedoc-plugin-nojekyll": "^1.0.1",
"typedoc-plugin-sourcefile-url": "^1.0.6",
"typescript": "^4.1.3"
}
}

@@ -1,39 +0,4 @@

import { RequestOptions } from '@ejnshtein/smol-request'
export * from './nyaa'
export * from './agent'
export interface Cookie {
domain?: string
expires?: Date
httponly?: boolean
path?: string
session?: string
}
export interface LoginPayload {
username: string
password: string
csrf_token?: string
}
export type NyaaRequestOptions = RequestOptions & { baseUrl?: string }
export interface NyaaApiRequestResult<T> {
status: string
message?: string
data?: T
}
export interface AgentOptions {
host?: string
apiHost?: string
}
export interface SearchOptions {
filter?: number
category?: string
}
export interface GetTorrentOptions {
withComments?: boolean
}
export * from '../dist/index'

@@ -48,31 +48,31 @@ export interface Profile {

export interface ApiTorrent {
id: number
name: string
url: string
submitter: string
description: string
information: string
is_complete: boolean
is_remake: boolean
is_trusted: boolean
main_category: string
main_category_id: number
sub_category: string
sub_category_id: number
hash_b32: string
hash_hex: string
files: {
[x: string]: number
}
filesize: number
magnet: string
stats: {
downloads: number
leechers: number
seeders: number
}
creation_date: string
comments?: Comment[]
}
// export interface ApiTorrent {
// id: number
// name: string
// url: string
// submitter: string
// description: string
// information: string
// is_complete: boolean
// is_remake: boolean
// is_trusted: boolean
// main_category: string
// main_category_id: number
// sub_category: string
// sub_category_id: number
// hash_b32: string
// hash_hex: string
// files: {
// [x: string]: number
// }
// filesize: number
// magnet: string
// stats: {
// downloads: number
// leechers: number
// seeders: number
// }
// creation_date: string
// comments?: Comment[]
// }

@@ -109,3 +109,3 @@ export interface ViewTorrent {

export interface SearchFile {
export interface SearchTorrent {
id: number

@@ -130,3 +130,3 @@ category: {

}
entry: 'remake' | 'trusted' | null
entry: Entry
}

@@ -137,3 +137,21 @@

last_page: number
files: SearchFile[]
torrents: SearchTorrent[]
}
export interface RSSFile {
id: number
title: string
guid: string
description: string
pubDate: Date
seeders: number
leechers: number
downloads: number
infoHash: string
categoryId: string
category: string
size: string
comments: number
trusted: string
remake: string
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc