boredgame/oldApis/games/search/+server.ts

104 lines
2.8 KiB
TypeScript

import { error, json } from '@sveltejs/kit';
import db from '../../../../db';
import { asc, desc, eq, ilike, or } from 'drizzle-orm';
import { games } from '$db/schema';
import kebabCase from 'just-kebab-case';
import {
FilterSchema,
PaginationSchema,
SearchSchema,
SortSchema,
} from '$lib/validations/zod-schemas';
// Search a user's collection
export const GET = async ({ url, locals }) => {
const searchParams = Object.fromEntries(url.searchParams);
const searchGames = PaginationSchema.merge(FilterSchema)
.merge(SortSchema)
.merge(SearchSchema)
.parse(searchParams);
if (searchGames.status !== 'success') {
error(400, 'Invalid request');
}
const q = searchParams?.q?.trim() || '';
const limit = parseInt(searchParams?.limit) || 10;
const skip = parseInt(searchParams?.skip) || 0;
const order: OrderDirection = searchParams?.order === 'desc' ? 'desc' : 'asc';
const exact = searchParams?.exact === 'true';
let orderBy = searchParams?.orderBy || 'slug';
if (orderBy === 'name') {
orderBy = 'slug';
}
console.log(
`q: ${q}, limit: ${limit}, skip: ${skip}, order: ${order}, exact: ${exact}, orderBy: ${orderBy}`,
);
console.log(exact);
if (exact) {
console.log('Exact Search API');
const game = await db.query.games.findFirst({
where: eq(games.name, q),
columns: {
id: true,
name: true,
slug: true,
thumb_url: true,
},
});
if (!game) {
error(404, { message: 'No games found' });
}
const foundGames = [game];
console.log('Games found in Exact Search API', JSON.stringify(foundGames, null, 2));
return json(foundGames);
} else {
const foundGames =
(await db
.select({
id: games.id,
name: games.name,
slug: games.slug,
thumb_url: games.thumb_url,
})
.from(games)
.where(or(ilike(games.name, `%${q}%`), ilike(games.slug, `%${kebabCase(q)}%`)))
.orderBy(getOrderDirection(order)(getOrderBy(orderBy)))
.offset(skip)
.limit(limit)) || [];
// const foundGames = await db.select({
// id: games.id,
// name: games.name,
// slug: games.slug,
// thumb_url: games.thumb_url
// })
// .from(games)
// .where(sql`to_tsvector('simple', ${games.name}) || to_tsvector('simple', ${games.slug}) @@ to_tsquery('simple', ${q})`)
// .orderBy(sql`${orderBy} ${order}`).offset(skip).limit(limit) || [];
if (foundGames.length === 0) {
error(404, { message: 'No games found' });
}
console.log('Games found in Search API', JSON.stringify(foundGames, null, 2));
return json(foundGames);
}
};
type OrderDirection = 'asc' | 'desc';
const getOrderDirection = (direction: OrderDirection) => {
return direction === 'asc' ? asc : desc;
};
const getOrderBy = (orderBy: string) => {
switch (orderBy) {
case 'name':
return games.name;
case 'slug':
return games.slug;
default:
return games.slug;
}
};