rsshub
Version:
Make RSS Great Again!
136 lines (133 loc) • 4.96 kB
JavaScript
import { n as init_esm_shims, t as __dirname } from "./esm-shims-CzJ_djXG.mjs";
import { t as art } from "./render-BQo6B4tL.mjs";
import { t as invalid_parameter_default } from "./invalid-parameter-rr4AgGpp.mjs";
import path from "node:path";
import queryString from "query-string";
import { GenreNotation, NarouNovelFetch, R18Site, SearchBuilder, SearchBuilderR18 } from "narou";
//#region lib/routes/syosetu/types/search.ts
init_esm_shims();
let SyosetuSub = /* @__PURE__ */ function(SyosetuSub$1) {
SyosetuSub$1["YOMOU"] = "yomou";
SyosetuSub$1["NOCTURNE"] = "noc";
SyosetuSub$1["MOONLIGHT"] = "mnlt";
SyosetuSub$1["MIDNIGHT"] = "mid";
return SyosetuSub$1;
}({});
const syosetuSubToJapanese = {
[SyosetuSub.YOMOU]: "小説を読もう",
[SyosetuSub.NOCTURNE]: "ノクターン",
[SyosetuSub.MOONLIGHT]: "ムーンライト",
[SyosetuSub.MIDNIGHT]: "ミッドナイト"
};
//#endregion
//#region lib/routes/syosetu/search.ts
const route = {
path: "/search/:sub/:query",
categories: ["reading"],
example: "/syosetu/search/noc/word=ハーレム¬word=&type=r&mintime=&maxtime=&minlen=30000&maxlen=&min_globalpoint=&max_globalpoint=&minlastup=&maxlastup=&minfirstup=&maxfirstup=&isgl=1¬bl=1&order=new?limit=5",
parameters: {
sub: {
description: "The target Syosetu subsite.",
options: Object.entries(SyosetuSub).map(([, value]) => ({
value,
label: syosetuSubToJapanese[value]
}))
},
query: "Search parameters in Syosetu format."
},
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false
},
name: "Search",
maintainers: ["SnowAgar25"],
handler
};
const setIfExists = (value) => value ?? void 0;
/**
* This function converts query string generated by Syosetu website into API-compatible format.
* It is not intended for users to freely adjust values.
*
* @see https://deflis.github.io/node-narou/index.html
* @see https://dev.syosetu.com/man/api/
*/
function mapToSearchParams(query, limit) {
const params = queryString.parse(query);
const searchParams = {
gzip: 5,
lim: limit,
word: setIfExists(params.word),
notword: setIfExists(params.notword),
title: setIfExists(params.title),
ex: setIfExists(params.ex),
keyword: setIfExists(params.keyword),
wname: setIfExists(params.wname),
sasie: setIfExists(params.sasie),
iszankoku: setIfExists(params.iszankoku),
isbl: setIfExists(params.isbl),
isgl: setIfExists(params.isgl),
istensei: setIfExists(params.istensei),
istenni: setIfExists(params.istenni),
stop: setIfExists(params.stop),
notzankoku: setIfExists(params.notzankoku),
notbl: setIfExists(params.notbl),
notgl: setIfExists(params.notgl),
nottensei: setIfExists(params.nottensei),
nottenni: setIfExists(params.nottenni),
minlen: setIfExists(params.minlen),
maxlen: setIfExists(params.maxlen),
type: setIfExists(params.type),
order: setIfExists(params.order),
genre: setIfExists(params.genre),
nocgenre: setIfExists(params.nocgenre)
};
if (params.mintime || params.maxtime) searchParams.time = `${params.mintime || ""}-${params.maxtime || ""}`;
return searchParams;
}
const isGeneral = (sub) => sub === SyosetuSub.YOMOU;
function createNovelSearchBuilder(sub, searchParams) {
if (isGeneral(sub)) return new SearchBuilder(searchParams, new NarouNovelFetch());
const r18Params = { ...searchParams };
switch (sub) {
case SyosetuSub.NOCTURNE:
r18Params.nocgenre = R18Site.Nocturne;
break;
case SyosetuSub.MOONLIGHT:
if (!r18Params.nocgenre) r18Params.nocgenre = [R18Site.MoonLight, R18Site.MoonLightBL].join("-");
break;
case SyosetuSub.MIDNIGHT:
r18Params.nocgenre = R18Site.Midnight;
break;
default: throw new invalid_parameter_default("Invalid Syosetu subsite.\nValid subsites are: yomou, noc, mnlt, mid");
}
return new SearchBuilderR18(r18Params, new NarouNovelFetch());
}
async function handler(ctx) {
const { sub, query } = ctx.req.param();
const searchUrl = `https://${sub}.syosetu.com/search/search/search.php?${query}`;
const searchParams = mapToSearchParams(query, Math.min(Number(ctx.req.query("limit") ?? 40), 40));
const items = (await createNovelSearchBuilder(sub, searchParams).execute()).values.map((novel) => ({
title: novel.title,
link: `https://${isGeneral(sub) ? "ncode" : "novel18"}.syosetu.com/${String(novel.ncode).toLowerCase()}`,
description: art(path.join(__dirname, "templates/description-e1f33e28.art"), {
novel,
genreText: GenreNotation[novel.genre]
}),
author: novel.writer,
category: novel.keyword.split(/[\s/\uFF0F]/).filter(Boolean)
}));
const searchTerms = [];
if (searchParams.word) searchTerms.push(searchParams.word);
if (searchParams.notword) searchTerms.push(`-${searchParams.notword}`);
return {
title: searchTerms.length > 0 ? `Syosetu Search: ${searchTerms.join(" ")}` : "Syosetu Search",
link: searchUrl,
item: items
};
}
//#endregion
export { route };