# API Documentation

- [API Documentation](#api-documentation)
  - [TL;DR](#tldr)
    - [install](#install)
    - [basic usage](#basic-usage)
  - [Types](#types)
    - [NHentai](#nhentai)
    - [NHSearchResults](#nhsearchresults)
    - [NHHentai](#nhhentai)
    - [NHTag](#nhtag)
    - [NHHentaiPartial](#nhhentaipartial)
    - [NHComment](#nhcomment)
    - [NHUser](#nhuser)
    - [NHSort](#nhsort)

## TL;DR
### install
```shell
npm i nhentai.js-api
```
### basic usage
```typescript
import { NHentai } from 'nhentai.js-api';
// or
const NHentai = require('nhentai.js-api');

const nhentai = new NHentai();

// Get hentai
const hentai = await nhentai.random(/*true if desire only english*/);
const hentai = await nhentai.hentai(174238);
const hentai = await nhentai.hentai('https://nhentai.net/g/174238');
const hentai = await nhentai.hentai('https://nhentai.net/random');

const comments = await hentai.comments();
for (const comment of comments) {
    const user = await comment.user();
    console.log(comment.body);
    if (user.about) {
        console.log(user.about);
    }
}

doSomething(hentai);

const results = await nhentai.search('langauge:english catgirl');
// ^ see https://nhentai.net/info/ for more info about searching

doSomethingElse(results);
```

## Types
In typescript you can import all these types by doing:
```typescript
import { NHentai, <type_name1>, <tyoe_name_2> } from 'nhentai.js-api';
```

### NHentai
```typescript
class NHentai {
    static readonly nhentaiRegex: RegExp;
    /**
     * @throws if number is negative
     * @throws if url is falsey or does not match NHentai.nhentaiRegex
     */
    hentai(url: number | string): Promise<NHHentai>;
    /**
     * Get a random hentai
     *
     * @param english true if random hentai should be english
     * @returns a random hentai
     */
    random(english: boolean): Promise<NHHentai>;
    /**
     * Get an nhentai user
     *
     * To get a user you need both the id and their username
     * Basically you never have to use this, because you can get users from comments
     * 
     * @param id user id
     * @param slug user name but sug form
     * @returns a random hentai
     */
    user(id: number, slug: string): Promise<NHUser>;
    /**
     * Search for a hentai on nhentai.net
     *
     * @returns {Promise<NHSearchResults>} search results
     */
    search(query: string, sort?: NHSort): Promise<NHSearchResults>;
}
```

### NHSearchResults
```typescript
class NHSearchResults {
    readonly search: string; // what you searched for
    readonly sort: NHSort; // what you sorted on
    readonly url: string; // url that's being scraped
    readonly api: NHentai; // NHentai instance
    hentai: NHHentaiPartial[]; // Hentai on current page
    total: number; // Total hentai found
    pages: number; // Total pages
    page: number; // Current page
    constructor(api: NHentai, query: string, sort?: NHSort);
    /**
     * Lookup is used to get the first page and initiate all values
     * @example
     * const results = new NHSearchResults(new NHentai(), 'english', NHSort.today);
     * await results.lookup();
     * 
     * You should just use NHentai#search() instead of constructing this yourself :3
     */
    lookup(): Promise<this>;
    next(): Promise<this>; // next page if there is one
    goto(page: number): Promise<this>; // goto a specific page
    previous(): Promise<this>; // previous page is there is one
}
```

### NHHentai
```typescript
interface NHHentai {
    title: string; // Full title
    cleanTitle: string; // Title without anything between brackets
    id: number; // Hentai id
    url: string; // Url to hentai
    cover: string; // Cover image of the hentai
    images: string[]; // Array of all images/pages in urls
    thumbnails: string[]; // Array of all thumbnails of pages in urls
    tags: {
        tags: NHTag[]; // array of tags
        parodies: NHTag[]; // array of parodies
        characters: NHTag[]; // etc...
        artists: NHTag[];
        groups: NHTag[];
        languages: NHTag[];
        categories: NHTag[];
    };
    uploaded: number; // ms since unix epoch
    pages: number; // amount of pages (same as images.length)
    recommended: NHHentaiPartial[]; // Array of recommended hentai
    comments: () => Promise<NHComment[]>; // Promise returning array of comments
}
```

### NHTag
```typescript
interface NHTag {
    name: string; // tagname eg. 'english'
    amount: number; // amount of hentai with this tag eg. 84000
    amountString: string; // eg. 84K
}
```

### NHHentaiPartial
```typescript
interface NHHentaiPartial {
    title: string; // see NHHentai
    cleanTitle: string; // ~
    id: number; // ~
    url: string; // ~
    cover: string; // ~
    language: NHLanguage; // No tags, only one language
    fetch: () => Promise<NHHentai>; // Get the full NHHentai object
}
```

### NHComment
```typescript
// realized nhentai had something of an api, this is an object returned from it (explains why it's in snake_case)
interface NHComment {
    id: number; // Comment id
    gallery_id: number; // Hentai id
    poster: { // Comment poster
        id: number; // Poser id
        username: string;
        slug: string; // https://nhentai.net/users/{slug}/{id}
        url: string; // ^
        avatar_url: string; // Url to avatar
        is_superuser: boolean;
        is_staff: boolean;
    };
    post_date: number; // Date the comment was posted
    body: string; // Body of the comment
    hentai: () => Promise<NHHentai>; // Get the hentai the comment was placed on
    user: () => Promise<NHUser>; // Get the nhentai user
}
```

### NHUser
```typescript
interface NHUser {
    avatar: string; // avatar url
    username: string;
    joined: number; // ms since unix epoch
    favoriteTags?: string | null; // string containing some of their favorite tags
    about?: string | null; // string containing some about theirself
    recentFavorites: NHHentaiPartial[]; // Hentai the user recently favorited
    recentComments: NHComment[]; // Recent comments the user posted
}
```

### NHSort
```typescript
// Enum used in NHentai#search()
enum NHSort {
    recent, // (default) sort on recent
    today, // 500 max results uploaded recently
    week, // 500 max results uploaded recently
    all_time // popular hentai first
}
```