import { Hono } from "hono"; import innertube from "../lib/innertube.js"; import { zValidator } from "@hono/zod-validator"; import { SearchVideos } from "../models/SearchVideos.js"; import search from "../templates/search.js"; import { YTNodes } from "youtubei.js"; const video = new Hono(); video.get( "/videos", zValidator("query", SearchVideos), async (c) => { const params = c.req.valid("query"); const page = params["start-index"] ?? 1; if (page > 5) { return c.html(search([], "")); } // * fetch all videos up to current page const allVideos: YTNodes.Video[] = []; let searchQuery = await innertube.search(params.q, { duration: params.duration, upload_date: params.time, sort_by: params.orderby }); for (let i = 1; i <= page; i++) { const videos = searchQuery.results.filter( (node): node is YTNodes.Video => node.type === "Video" ); allVideos.push(...videos); if (i < page) { try { const nextPage = await searchQuery.getContinuation(); if (!nextPage) break; searchQuery = nextPage; } catch (err) { // * no more pages available break; } } } // * build next page URL const nextUrl = new URL(c.req.url); nextUrl.searchParams.set("start-index", (page + 1).toString()); return c.html(search(allVideos, nextUrl.toString())); } ); export default video;