From ce96fe7970f8681f5ecf52801fe02b083b3fc232 Mon Sep 17 00:00:00 2001 From: XLor Date: Thu, 5 Oct 2023 16:34:50 +0800 Subject: [PATCH] feat(animegarden): js version of database filter --- packages/animegarden/src/garden/filter.ts | 60 +++++++++++++++++++++++ packages/animegarden/src/garden/index.ts | 8 +-- 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 packages/animegarden/src/garden/filter.ts diff --git a/packages/animegarden/src/garden/filter.ts b/packages/animegarden/src/garden/filter.ts new file mode 100644 index 00000000..8fa92f81 --- /dev/null +++ b/packages/animegarden/src/garden/filter.ts @@ -0,0 +1,60 @@ +import type { Resource } from '../types'; + +import type { FilterOptions } from './types'; + +import { parseSearchURL } from './url'; +import { normalizeTitle } from './utils'; + +export function makeResourcesFilter( + options: Omit +): (resource: Resource) => boolean { + const resolved = parseSearchURL(new URLSearchParams(), options); + const chains: Array<(resource: Resource) => boolean> = []; + + if (resolved.fansubId) { + const fansubId = resolved.fansubId.map((id) => '' + id); + chains.push((r) => (r.fansub ? fansubId.includes(r.fansub.id) : false)); + } + if (resolved.fansubName) { + const fansubName = resolved.fansubName; + chains.push((r) => (r.fansub ? fansubName.includes(r.fansub.name) : false)); + } + if (resolved.publisherId) { + const publisherId = resolved.publisherId.map((id) => '' + id); + chains.push((r) => publisherId.includes(r.publisher.id)); + } + if (resolved.type) { + const type = resolved.type; + chains.push((r) => r.type === type); + } + if (resolved.before) { + const before = resolved.before.getTime(); + chains.push((r) => new Date(r.createdAt).getTime() <= before); + } + if (resolved.after) { + const after = resolved.after.getTime(); + chains.push((r) => new Date(r.createdAt).getTime() >= after); + } + + if (resolved.include || resolved.search) { + const include = resolved.include ?? []; + if (resolved.search) { + include.push(resolved.search); + } + chains.push((r) => { + // @ts-expect-error + const titleAlt: string = r.titleAlt || normalizeTitle(r.title); + return include.every((keys) => keys.some((key) => titleAlt.indexOf(key) !== -1)); + }); + } + if (resolved.exclude) { + const exclude = resolved.exclude; + chains.push((r) => { + // @ts-expect-error + const titleAlt: string = r.titleAlt || normalizeTitle(r.title); + return exclude.every((key) => titleAlt.indexOf(key) === -1); + }); + } + + return (res) => chains.every((fn) => fn(res)); +} diff --git a/packages/animegarden/src/garden/index.ts b/packages/animegarden/src/garden/index.ts index d922f76e..d5e5f08d 100644 --- a/packages/animegarden/src/garden/index.ts +++ b/packages/animegarden/src/garden/index.ts @@ -5,18 +5,20 @@ import type { FetchResourcesOptions, FetchResourceDetailOptions } from './types'; -import { stringifySearchURL } from './url'; import { retryFn } from './utils'; +import { stringifySearchURL } from './url'; export * from './url'; export * from './types'; -export { AllFansubs, findFansub } from './constant'; - export { normalizeTitle } from './utils'; +export { makeResourcesFilter } from './filter'; + +export { AllFansubs, findFansub } from './constant'; + export const DefaultBaseURL = 'https://garden.onekuma.cn/api/'; interface FetchResourcesResult {