https://github.com/h2owater425/node-hitomi
Hitomi.la api for Node.js
https://github.com/h2owater425/node-hitomi
api hitomi library typescript typescript-library
Last synced: 3 months ago
JSON representation
Hitomi.la api for Node.js
- Host: GitHub
- URL: https://github.com/h2owater425/node-hitomi
- Owner: H2Owater425
- License: mit
- Created: 2021-05-24T01:50:50.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2024-12-23T08:34:35.000Z (over 1 year ago)
- Last Synced: 2025-02-23T20:19:25.786Z (over 1 year ago)
- Topics: api, hitomi, library, typescript, typescript-library
- Language: TypeScript
- Homepage: https://npm.im/node-hitomi
- Size: 387 KB
- Stars: 18
- Watchers: 1
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://github.com/H2Owater425/node-hitomi)
### Hitomi.la API for Node.js
Would you call me a gentleman?
[](https://npmjs.org/package/node-hitomi)
[](https://npmjs.org/package/node-hitomi)
[](https://github.com/H2Owater425/node-hitomi/blob/main/LICENSE)
## Installation
> [!IMPORTANT]
>
> Due to frequent changes on Hitomi.la, it is highly recommended to use the latest version.
**Node.js 10.20 or newer is required.**
```sh
npm install node-hitomi
yarn add node-hitomi
pnpm add node-hitomi
bun add node-hitomi
```
## Features
- **Gallery Search:** Filter by tags and title, choose sort order, and paginate results.
- **Gallery Retrieval:** Load full gallery metadata, including title, type, language, artists, and relations.
- **Tag Management:** Create, parse, search, and list tags. Also list available languages for a tag.
- **Image Downloads:** Resolve URLs and fetch images in AVIF/WebP/JXL (when available), with optional thumbnail sizes.
- **Video Downloads:** Fetch gallery videos and poster images.
## Usage
The package exports a default client instance, but you can also create your own client for custom configuration.
```typescript
import { Hitomi } from 'node-hitomi';
import { Agent } from 'https';
const agent = new Agent({
keepAlive: true,
// Bypass server name indication field blocking
servername: '',
rejectUnauthorized: false
});
const hitomi = new Hitomi({
agent: agent,
indexMaximumAge: 300000,
imageContextMaximumAge: 1800000
});
```
If you use CommonJS module:
```typescript
const { hitomi, SortType /* and more... */ } = require('node-hitomi');
```
---
### Galleries
`GalleryManager` lets you retrieve individual galleries and list matching gallery references.
#### `GalleryManager.retrieve(id)`
Retrieves a full gallery by id and returns a `Gallery` instance.
```typescript
import hitomi from 'node-hitomi';
// Retrieve a gallery by id
const gallery = await hitomi.galleries.retrieve(123456);
console.log(`Title: ${gallery.title.display}`);
console.log(`Type: ${gallery.type}`);
console.log(`Language: ${gallery.language?.name}`);
```
#### `GalleryManager.list(options?)`
Lists galleries that match the given criteria. You can pass tags, a title query, sort options, and paging options. The method returns `GalleryReference[]`.
```typescript
import hitomi, { SortType } from 'node-hitomi';
// Parse a search expression into structured tag objects
const tags = hitomi.tags.parse('male:sole_male -female:netorare series:blue_archive');
// List matching gallery references
const references = await hitomi.galleries.list({
tags: tags,
title: 'serina',
orderBy: SortType.PopularityMonth
});
// Resolve the first reference to a full gallery
if(references.length > 0) {
const firstGallery = await references[0].retrieve();
console.log(firstGallery.title.display);
}
```
> [!WARNING]
>
> Not every `options.page` usage is valid. It must meet the restrictions below.
>
> - Only one non-language tag is allowed (optionally combined with a language tag).
> - Negative tags and title are not supported.
>
> ```typescript
> const simpleTags = hitomi.tags.parse('type:manga language:english');
>
> // List matching gallery references with pagination
> const pagedReferences = await hitomi.galleries.list({
> tags: simpleTags,
> orderBy: SortType.DatePublished,
> page: {
> index: 0,
> size: 25
> }
> });
>
> console.log(pagedReferences, `(${pagedReferences['length']} galleries)`);
> ```
---
### Tags
`TagManager` helps you create, parse, search, and list tags.
#### `TagManager.create(type, name, isNegative?)`
Creates a `Tag` instance with a type, name, and optional negation flag.
```typescript
import hitomi from 'node-hitomi';
// Create a series tag and list available languages for that tag
const tag = hitomi.tags.create('series', 'trickcal_revive', false);
const languages = await tag.listLanguages();
console.log(languages);
```
#### `TagManager.parse(expression)`
Parses a human-readable expression into unique `Tag` instances. The expected format is `[-]type:name`, where spaces are represented by underscores.
```typescript
import hitomi from 'node-hitomi';
// Parse a string expression into Tag instances
const parsedTags = hitomi.tags.parse('female:yandere male:sole_male -tag:group');
console.log(parsedTags);
```
#### `TagManager.search(term)`
Searches tags by partial term and returns tuples of `[Tag, count]`, where `count` is the number of galleries associated with each tag.
```typescript
import hitomi from 'node-hitomi';
// Search tags and print their gallery counts
const tagAndCounts = await hitomi.tags.search('character:agnes');
for(const [tag, count] of tagAndCounts) {
console.log(`${String(tag)} (${count} galleries)`);
}
```
#### `TagManager.list(type, startsWith?)`
Lists tags of a specific type, optionally filtered by an initial character.
```typescript
import hitomi, { NameInitial } from 'node-hitomi';
// List female tags that start with 'a'
const femaleATags = await hitomi.tags.list('female', NameInitial.A);
for(const tag of femaleATags) {
console.log(String(tag));
}
```
---
### Media
#### `Image.resolveUrl(extension, thumbnailSize?)`
Resolves an image URL in the requested format and optional thumbnail size.
> [!WARNING]
>
> Not every `extension` and `thumbnailSize` combination is valid. It must meet the restrictions below.
>
> | Thumbnail Size | Extension | Requirement (must be true) |
> | :------------- | :-------- | :------------------------------- |
> | *(none)* | *(all)* | `has{Extension}` |
> | `Small` | *(all)* | `has{Extension}` |
> | `Medium` | `Avif` | `hasThumbnail && has{Extension}` |
> | `Big` | *(all)* | `hasThumbnail && has{Extension}` |
```typescript
import hitomi, { Extension, ThumbnailSize } from 'node-hitomi';
// Retrieve a gallery by id and get thumbnail available images
const gallery = await hitomi.galleries.retrieve(123456);
const thumbnails = gallery.getThumbnails();
// Full-size WebP URL
const imageUrl = await thumbnails[0].resolveUrl(Extension.Webp);
console.log(`Image URL: ${imageUrl}`);
// AVIF medium thumbnail URL
const thumbnailUrl = await thumbnails[1].resolveUrl(Extension.Avif, ThumbnailSize.Medium);
console.log(`Thumbnail URL: ${thumbnailUrl}`);
```
#### `Image.fetch(extension, thumbnailSize?)`
Fetches an image as a `Buffer`. The same extension and thumbnail constraints as [`Image.resolveUrl`](#imageresolveurlextension-thumbnailsize) apply.
```typescript
import hitomi, { Extension, ThumbnailSize } from 'node-hitomi';
import { writeFileSync } from 'fs';
// Retrieve a gallery by id and get thumbnail available images
const gallery = await hitomi.galleries.retrieve(123456);
const thumbnails = gallery.getThumbnails();
// Fetch and save a full-size image
const imageBuffer = await thumbnails[0].fetch(Extension.Webp);
writeFileSync('image.webp', imageBuffer);
// Fetch and save a medium thumbnail
const thumbnailBuffer = await thumbnails[1].fetch(Extension.Avif, ThumbnailSize.Medium);
writeFileSync('thumbnail.avif', thumbnailBuffer);
```
#### `Video.fetch()`
Fetches a gallery video as an MP4 `Buffer`.
```typescript
import hitomi from 'node-hitomi';
import { writeFileSync } from 'fs';
const gallery = await hitomi.galleries.retrieve(123456);
if(gallery.video) {
// Fetch and store the MP4 video
const videoBuffer = await gallery.video.fetch();
writeFileSync('video.mp4', videoBuffer);
}
```
#### `Video.fetchPoster()`
Fetches the video poster as a WebP `Buffer`.
```typescript
import hitomi from 'node-hitomi';
import { writeFileSync } from 'fs';
const gallery = await hitomi.galleries.retrieve(123456);
if(gallery.video) {
// Fetch and store the WebP poster image
const posterBuffer = await gallery.video.fetchPoster();
writeFileSync('poster.webp', posterBuffer);
}
```
## Contribution
Contributions are welcome. Feel free to open an issue for bugs or submit a pull request with improvements.
## License
This project is licensed under the [MIT License](LICENSE).