multporn-api-sdk 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -135
- package/dist/browser/index.js +1863 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/node/index.cjs +1884 -0
- package/dist/node/index.cjs.map +1 -0
- package/dist/node/index.js +1858 -0
- package/dist/node/index.js.map +1 -0
- package/dist/rn/index.js +1863 -0
- package/dist/rn/index.js.map +1 -0
- package/dist/types/index.d.ts +218 -0
- package/dist/types/index.js +1824 -0
- package/package.json +41 -15
package/README.md
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `multporn-api-sdk`
|
|
2
2
|
|
|
3
|
-
**Unofficial**
|
|
3
|
+
**Unofficial** typed SDK for Multiporn HTML parsing. It works in **Node 18+** and in **Expo/React Native** (without Node-stdlib), uses `fetch` + `AbortController' (timeouts/delays), `cheerio` for parsing, supports:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
* feeds/hubs (including pagination),
|
|
6
|
+
* **alphabetical** lists,
|
|
7
|
+
* **search** (HTML → fallback on Drupal AJAX),
|
|
8
|
+
* **posts/viewer** (images, videos, metadata, recommendations),
|
|
9
|
+
* "smart" route resolution (hub vs viewer).
|
|
10
|
+
|
|
11
|
+
> ⚠️ This is an **unofficial** scraper. Use it responsibly, follow the rules of the site and add cache/throttling in production.
|
|
6
12
|
|
|
7
13
|
---
|
|
8
14
|
|
|
@@ -11,76 +17,82 @@
|
|
|
11
17
|
```bash
|
|
12
18
|
yarn add multporn-api-sdk
|
|
13
19
|
# or
|
|
14
|
-
npm i
|
|
15
|
-
|
|
20
|
+
npm i multiporn-api-sdk
|
|
21
|
+
```
|
|
16
22
|
|
|
17
|
-
|
|
23
|
+
### Requirements and compatibility
|
|
24
|
+
|
|
25
|
+
* **Node**: ≥ **18.17** ( Cheerio 1.x requirement). ([GitHub][2])
|
|
26
|
+
* **Expo/React Native**: compatible out of the box (the library does not use standard Node library modules that are missing from RN/Expo). Details: Expo does not supply Node-stdlib ("`node:stream`", etc.) — this is correct and expected. ([Expo Documentation][1])
|
|
18
27
|
|
|
19
28
|
---
|
|
20
29
|
|
|
21
30
|
## Quick start
|
|
22
31
|
|
|
32
|
+
### Node / Bun / Deno (Node-compatible runtime)
|
|
33
|
+
|
|
23
34
|
```ts
|
|
24
|
-
import { MultpornClient } from '
|
|
35
|
+
import { MultpornClient } from 'multporn-api-sdk';
|
|
25
36
|
|
|
26
37
|
const mp = new MultpornClient({
|
|
27
|
-
baseURL: 'https://multporn.net',
|
|
38
|
+
baseURL: 'https://multporn.net',
|
|
28
39
|
timeoutMs: 15000,
|
|
29
40
|
retry: { retries: 3 },
|
|
30
41
|
});
|
|
31
42
|
|
|
32
|
-
// Latest posts (homepage “New”)
|
|
33
43
|
const latest = await mp.latest(0);
|
|
34
|
-
console.log(
|
|
44
|
+
console.log(latest.items.slice(0, 3));
|
|
35
45
|
|
|
36
|
-
// “Manga” hub
|
|
37
46
|
const manga = await mp.listByPath('/munga', 0);
|
|
38
|
-
console.log(
|
|
47
|
+
console.log(manga.items.length, manga.hasNext);
|
|
39
48
|
|
|
40
|
-
// Alphabet: letters for Manga
|
|
41
49
|
const letters = await mp.alphabetLetters('manga');
|
|
42
|
-
console.log('letters:', letters.map(l => l.label).join(' '));
|
|
43
|
-
|
|
44
|
-
// Alphabet: entries for letter A
|
|
45
50
|
const mangaA = await mp.alphabet('manga', 'A', 0);
|
|
46
|
-
// same via listByPath:
|
|
47
|
-
const mangaA2 = await mp.listByPath('/munga', 0, { letter: 'A' });
|
|
48
51
|
|
|
49
|
-
// Search
|
|
50
52
|
const found = await mp.search('naruto', 0);
|
|
51
|
-
console.log(
|
|
53
|
+
console.log(found.items.slice(0, 3));
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
console.log(post.title, 'images:', post.images?.length || 0);
|
|
55
|
+
const post = await mp.getPost('/comics/haywire');
|
|
56
|
+
console.log(post.title, post.images?.length || 0);
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
const resolved = await mp.resolveSmart('https://multporn.net/munga');
|
|
58
|
+
const resolved = await mp.resolveSmart('https://multporn.net/munga ');
|
|
59
59
|
if (resolved.route === 'listing') {
|
|
60
|
-
|
|
61
|
-
} else
|
|
62
|
-
console.log('
|
|
60
|
+
console.log('Hub, elements:', resolved.data.items.length);
|
|
61
|
+
} else {
|
|
62
|
+
console.log('Post, type:', resolved.data.viewer.kind);
|
|
63
63
|
}
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
### Expo / React Native
|
|
67
|
+
|
|
68
|
+
The library uses **only the Web API** (`fetch`, `AbortController') and does not pull `node:*`, so it can be connected directly:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { MultpornClient } from 'multporn-api-sdk';
|
|
72
|
+
|
|
73
|
+
const mp = new MultpornClient({ timeoutMs: 15000 });
|
|
74
|
+
|
|
75
|
+
export async function fetchLatest() {
|
|
76
|
+
const page0 = await mp.latest(0);
|
|
77
|
+
return page0.items; // draw a FlatList, etc.
|
|
78
|
+
}
|
|
79
|
+
```
|
|
67
80
|
|
|
68
|
-
|
|
81
|
+
> Note: Expo/RN does not contain modules of the Node standard library (for example, `node:stream`). This is standard: choose libraries that are independent of Node-stdlib (like this SDK). ([Expo Documentation][1])
|
|
69
82
|
|
|
70
|
-
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## API (overview)
|
|
71
86
|
|
|
72
87
|
```ts
|
|
73
88
|
new MultpornClient(options?: {
|
|
74
|
-
baseURL?: string;
|
|
75
|
-
timeoutMs?: number;
|
|
76
|
-
retry?: { retries?: number };
|
|
89
|
+
baseURL?: string;
|
|
90
|
+
timeoutMs?: number;
|
|
91
|
+
retry?: { retries?: number; factor?: number; minDelayMs?: number; maxDelayMs?: number };
|
|
77
92
|
headers?: Record<string, string>;
|
|
93
|
+
userAgent?: string;
|
|
78
94
|
})
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Client methods
|
|
82
95
|
|
|
83
|
-
```ts
|
|
84
96
|
latest(page?: number, params?: ListingQuery): Promise<Page<ListingItem>>
|
|
85
97
|
|
|
86
98
|
listByPath(
|
|
@@ -101,36 +113,32 @@ updates(params?: MultpornUpdatesParams): Promise<UpdatesResult>
|
|
|
101
113
|
|
|
102
114
|
viewUpdates(viewName: ViewName, params?: Omit<MultpornUpdatesParams, 'view_name'>): Promise<UpdatesResult>
|
|
103
115
|
|
|
104
|
-
alphabetLetters(section:
|
|
116
|
+
alphabetLetters(section: AlphabetSection): Promise<AlphabetLetter[]>
|
|
105
117
|
|
|
106
118
|
alphabet(section: AlphabetSection, letter: string, page?: number): Promise<Page<ListingItem>>
|
|
107
119
|
```
|
|
108
120
|
|
|
109
|
-
###
|
|
121
|
+
### Important types (simplified)
|
|
110
122
|
|
|
111
123
|
```ts
|
|
112
|
-
type ListingItem = {
|
|
113
|
-
title: string;
|
|
114
|
-
url: string;
|
|
115
|
-
thumb?: string;
|
|
116
|
-
};
|
|
124
|
+
type ListingItem = { title: string; url: string; thumb?: string; };
|
|
117
125
|
|
|
118
126
|
type Page<T> = {
|
|
119
127
|
items: T[];
|
|
120
128
|
page: number;
|
|
121
129
|
hasNext: boolean;
|
|
122
|
-
totalPages
|
|
130
|
+
totalPages?: number;
|
|
131
|
+
pageSize?: number;
|
|
132
|
+
alphabet?: AlphabetBlock;
|
|
133
|
+
sorting?: SortingUI;
|
|
123
134
|
};
|
|
124
135
|
|
|
125
136
|
type Post = {
|
|
126
|
-
url: string;
|
|
127
137
|
title: string;
|
|
128
|
-
|
|
129
|
-
images
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
tags?: string[];
|
|
133
|
-
recommendations?: ListingItem[];
|
|
138
|
+
url: string;
|
|
139
|
+
images: string[];
|
|
140
|
+
tags: string[];
|
|
141
|
+
author: string | null;
|
|
134
142
|
};
|
|
135
143
|
```
|
|
136
144
|
|
|
@@ -138,13 +146,11 @@ type Post = {
|
|
|
138
146
|
|
|
139
147
|
## Pagination
|
|
140
148
|
|
|
141
|
-
All listing methods return `Page<ListingItem>` with `page`, `hasNext`, and `totalPages`.
|
|
142
|
-
|
|
143
149
|
```ts
|
|
144
150
|
let p = 0;
|
|
145
151
|
for (;;) {
|
|
146
152
|
const page = await mp.listByPath('/munga', p);
|
|
147
|
-
//
|
|
153
|
+
// processing of page.items
|
|
148
154
|
if (!page.hasNext) break;
|
|
149
155
|
p += 1;
|
|
150
156
|
}
|
|
@@ -154,118 +160,60 @@ for (;;) {
|
|
|
154
160
|
|
|
155
161
|
## Search
|
|
156
162
|
|
|
157
|
-
|
|
163
|
+
First, the usual HTML output is parsed; if empty, Drupal AJAX (`/views/ajax`) is used. This covers different search patterns.
|
|
158
164
|
|
|
159
165
|
```ts
|
|
160
166
|
const res = await mp.search('genshin', 0);
|
|
161
167
|
res.items.forEach(i => console.log(i.title, i.url, i.thumb));
|
|
162
168
|
```
|
|
163
169
|
|
|
164
|
-
If you want to display category badges like “Comics”, “Manga”, “Pictures”, “Gay porn comics”, derive a label from the first URL path segment (e.g. `comics`, `hentai_manga`, `pictures`, `gay_porn_comics`) and show it next to the title.
|
|
165
|
-
|
|
166
170
|
---
|
|
167
171
|
|
|
168
172
|
## Alphabet
|
|
169
173
|
|
|
170
|
-
Some hubs expose an alphabet. Use:
|
|
171
|
-
|
|
172
174
|
```ts
|
|
173
|
-
const letters = await mp.alphabetLetters('manga');
|
|
174
|
-
const pageA = await mp.alphabet('manga', 'A', 0);
|
|
175
|
-
|
|
175
|
+
const letters = await mp.alphabetLetters('manga');
|
|
176
|
+
const pageA = await mp.alphabet('manga', 'A', 0);
|
|
177
|
+
|
|
178
|
+
// Equivalent via listByPath:
|
|
176
179
|
const pageA2 = await mp.listByPath('/munga', 0, { letter: 'A' });
|
|
177
180
|
```
|
|
178
181
|
|
|
179
182
|
---
|
|
180
183
|
|
|
181
|
-
##
|
|
182
|
-
|
|
183
|
-
`examples/dev-server.mjs` ships a ready-to-use Express server over the SDK. It includes HTML pages for quick UI testing, REST endpoints, media proxies, and Swagger docs.
|
|
184
|
-
|
|
185
|
-
### Features
|
|
186
|
-
|
|
187
|
-
* **HTML pages**
|
|
188
|
-
|
|
189
|
-
* `/hub?path=/munga[&letter=A][&page=0]` – hub preview with alphabet (pager hidden when there’s only one page)
|
|
190
|
-
* `/viewer?url=...` – post preview (images as a gallery, videos via embedded `player.html`)
|
|
191
|
-
* `/search?q=genshin[&page=0]` – search page with grouping and pagination
|
|
192
|
-
* **REST endpoints**
|
|
193
|
-
|
|
194
|
-
* `/api/list` – hub listing (root `/` serves “latest”)
|
|
195
|
-
* `/api/search` – search with pagination
|
|
196
|
-
* `/api/resolve` – smart route detection (hub vs post)
|
|
197
|
-
* `/api/post` – post details
|
|
198
|
-
* `/api/updates` – Drupal Views feeds (e.g., `new_mini`, `updated_manga`, etc.)
|
|
199
|
-
* `/api/alphabet/letters` – alphabet letters for a section
|
|
200
|
-
* `/api/alphabet/items` – items for a letter in a section
|
|
201
|
-
* **Proxies**
|
|
184
|
+
## Updates (Drupal Views)
|
|
202
185
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
* **Docs**
|
|
186
|
+
``ts
|
|
187
|
+
// universal
|
|
188
|
+
const upd = await mp.updates({ view_name: 'new_mini', first: 0, last: 8 });
|
|
207
189
|
|
|
208
|
-
|
|
190
|
+
// or wrapper presets
|
|
191
|
+
await mp.viewUpdates('updated_manga');
|
|
192
|
+
await mp.viewUpdates('random_top_comics');
|
|
193
|
+
```
|
|
209
194
|
|
|
210
|
-
|
|
195
|
+
---
|
|
211
196
|
|
|
212
|
-
|
|
213
|
-
* `HOST` – bind host (default: `0.0.0.0`)
|
|
214
|
-
* `PORT` – server port (default: `5173`)
|
|
215
|
-
* `PUBLIC_BASE_URL` – public base URL (for links in OpenAPI/Swagger)
|
|
197
|
+
## Example of a dev server (for testing the SDK in the repository)
|
|
216
198
|
|
|
217
|
-
|
|
199
|
+
The repo has an example of an Express server with HTML pages and REST endpoints (Swagger/OpenAPI). It is **not required** for the Expo application, but it is convenient for debugging in a Node environment.
|
|
218
200
|
|
|
219
201
|
```bash
|
|
220
|
-
#
|
|
202
|
+
#1) Build SDK (dist/*)
|
|
221
203
|
npm run build
|
|
222
204
|
|
|
223
|
-
#
|
|
205
|
+
#2) Run an example
|
|
224
206
|
node examples/dev-server.mjs
|
|
225
207
|
|
|
226
|
-
#
|
|
208
|
+
# Open:
|
|
227
209
|
# http://localhost:5173/docs
|
|
228
210
|
# http://localhost:5173/hub?path=/munga
|
|
229
211
|
# http://localhost:5173/search?q=genshin
|
|
230
212
|
# http://localhost:5173/viewer?url=https://multporn.net/comics/...
|
|
231
213
|
```
|
|
232
214
|
|
|
233
|
-
### REST examples
|
|
234
|
-
|
|
235
|
-
```bash
|
|
236
|
-
# Search
|
|
237
|
-
curl 'http://localhost:5173/api/search?q=genshin&page=0'
|
|
238
|
-
|
|
239
|
-
# Hub listing (page 0)
|
|
240
|
-
curl 'http://localhost:5173/api/list?path=/munga&page=0'
|
|
241
|
-
|
|
242
|
-
# Latest (homepage)
|
|
243
|
-
curl 'http://localhost:5173/api/list?page=0'
|
|
244
|
-
|
|
245
|
-
# Post
|
|
246
|
-
curl 'http://localhost:5173/api/post?url=https://multporn.net/comics/haywire'
|
|
247
|
-
|
|
248
|
-
# Smart resolve
|
|
249
|
-
curl 'http://localhost:5173/api/resolve?url=https://multporn.net/munga'
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
---
|
|
253
|
-
|
|
254
|
-
## Swagger / OpenAPI
|
|
255
|
-
|
|
256
|
-
The dev server serves an extended OpenAPI spec at `/openapi.json` and Swagger UI at `/docs`. All HTML pages and REST endpoints are listed with parameters, responses, and example payloads to simplify testing and integration.
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
|
|
260
|
-
## Frontend tips
|
|
261
|
-
|
|
262
|
-
* Always load thumbs through the image proxy: `/img?url=…`.
|
|
263
|
-
* Some cards may not have a `thumb`. Show a placeholder (e.g., “No image available”) instead of leaving the image empty.
|
|
264
|
-
* For search results, derive a readable badge from the first URL segment (e.g., `comics`, `hentai_manga`, `pictures`, `gay_porn_comics`) and prefix the title with it to clarify the type.
|
|
265
|
-
|
|
266
215
|
---
|
|
267
216
|
|
|
268
|
-
##
|
|
217
|
+
## License
|
|
269
218
|
|
|
270
|
-
|
|
271
|
-
* If site structure changes, update parsers accordingly.
|
|
219
|
+
MIT
|