Updating MeltUI and adding APIs for external searching games on BGG.

This commit is contained in:
Bradley Shellnut 2023-09-29 21:06:46 +13:00
parent b25af709e2
commit e69ed91e2c
4 changed files with 205 additions and 16 deletions

View file

@ -73,14 +73,15 @@
"@fontsource/fira-mono": "^4.5.10",
"@iconify-icons/line-md": "^1.2.26",
"@iconify-icons/mdi": "^1.2.47",
"@lucia-auth/adapter-mysql": "^2.0.0",
"@lucia-auth/adapter-mysql": "^2.1.0",
"@lucia-auth/adapter-prisma": "^3.0.1",
"@lukeed/uuid": "^2.0.1",
"@melt-ui/svelte": "^0.37.6",
"@melt-ui/svelte": "^0.50.0",
"@prisma/client": "5.3.1",
"@types/feather-icons": "^4.29.1",
"@vercel/og": "^0.5.13",
"bits-ui": "^0.0.27",
"boardgamegeekclient": "^1.9.1",
"class-variance-authority": "^0.6.1",
"clsx": "^1.2.1",
"cookie": "^0.5.0",

View file

@ -18,8 +18,8 @@ dependencies:
specifier: ^1.2.47
version: 1.2.47
'@lucia-auth/adapter-mysql':
specifier: ^2.0.0
version: 2.0.0(lucia@2.7.0)
specifier: ^2.1.0
version: 2.1.0(lucia@2.7.0)
'@lucia-auth/adapter-prisma':
specifier: ^3.0.1
version: 3.0.1(@prisma/client@5.3.1)(lucia@2.7.0)
@ -27,8 +27,8 @@ dependencies:
specifier: ^2.0.1
version: 2.0.1
'@melt-ui/svelte':
specifier: ^0.37.6
version: 0.37.6(svelte@4.2.1)
specifier: ^0.50.0
version: 0.50.0(svelte@4.2.1)
'@prisma/client':
specifier: 5.3.1
version: 5.3.1(prisma@5.3.1)
@ -41,6 +41,9 @@ dependencies:
bits-ui:
specifier: ^0.0.27
version: 0.0.27(@sveltejs/kit@1.25.1)(svelte@4.2.1)
boardgamegeekclient:
specifier: ^1.9.1
version: 1.9.1
class-variance-authority:
specifier: ^0.6.1
version: 0.6.1
@ -99,7 +102,7 @@ dependencies:
devDependencies:
'@melt-ui/pp':
specifier: ^0.1.2
version: 0.1.2(@melt-ui/svelte@0.37.6)(svelte@4.2.1)
version: 0.1.2(@melt-ui/svelte@0.50.0)(svelte@4.2.1)
'@playwright/test':
specifier: ^1.37.0
version: 1.37.0
@ -1063,15 +1066,32 @@ packages:
resolution: {integrity: sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ==}
dependencies:
'@floating-ui/utils': 0.1.1
dev: false
/@floating-ui/core@1.5.0:
resolution: {integrity: sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg==}
dependencies:
'@floating-ui/utils': 0.1.4
/@floating-ui/dom@1.5.1:
resolution: {integrity: sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw==}
dependencies:
'@floating-ui/core': 1.4.1
'@floating-ui/utils': 0.1.1
dev: false
/@floating-ui/dom@1.5.3:
resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==}
dependencies:
'@floating-ui/core': 1.5.0
'@floating-ui/utils': 0.1.4
/@floating-ui/utils@0.1.1:
resolution: {integrity: sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==}
dev: false
/@floating-ui/utils@0.1.4:
resolution: {integrity: sha512-qprfWkn82Iw821mcKofJ5Pk9wgioHicxcQMxx+5zt5GSKoqdWvgG5AxVmpmUUjzTLPVSH5auBrhI93Deayn/DA==}
/@fontsource/fira-mono@4.5.10:
resolution: {integrity: sha512-bxUnRP8xptGRo8YXeY073DSpfK74XpSb0ZyRNpHV9WvLnJ7TwPOjZll8hTMin7zLC6iOp59pDZ8EQDj1gzgAQQ==}
@ -1154,8 +1174,8 @@ packages:
'@jridgewell/resolve-uri': 3.1.0
'@jridgewell/sourcemap-codec': 1.4.15
/@lucia-auth/adapter-mysql@2.0.0(lucia@2.7.0):
resolution: {integrity: sha512-8a4JZ3VjDyRu/mAop2hEt/jOJO2HXwWIAid6a4wGiR8wgnlyOws9brRc+/wxQHSOlWUlrWemrfDvXLs5mMtkeQ==}
/@lucia-auth/adapter-mysql@2.1.0(lucia@2.7.0):
resolution: {integrity: sha512-LkqsJHQS9KuMs+cTJQJnaqb6obqMyJfblyyLM0Ogoimzikb5orbkWI0C8eY3Supr60bgP4PYuQxYZm8xxera0Q==}
peerDependencies:
'@planetscale/database': ^1.0.0
lucia: ^2.0.0
@ -1208,14 +1228,14 @@ packages:
- encoding
- supports-color
/@melt-ui/pp@0.1.2(@melt-ui/svelte@0.37.6)(svelte@4.2.1):
/@melt-ui/pp@0.1.2(@melt-ui/svelte@0.50.0)(svelte@4.2.1):
resolution: {integrity: sha512-GZeqp7UWLNZUC2dJpREnZrWMR88vy27WO7C3cIBz4KW3/CFD19FjNkd3VbSRfcRryrMkdnEs9nu2VUa8/0u58w==}
engines: {pnpm: '>=8.6.3'}
peerDependencies:
'@melt-ui/svelte': '>= 0.29.0'
svelte: ^3.55.0 || ^4.0.0
dependencies:
'@melt-ui/svelte': 0.37.6(svelte@4.2.1)
'@melt-ui/svelte': 0.50.0(svelte@4.2.1)
svelte: 4.2.1
dev: true
@ -1231,14 +1251,15 @@ packages:
svelte: 4.2.1
dev: false
/@melt-ui/svelte@0.37.6(svelte@4.2.1):
resolution: {integrity: sha512-rh3d1FN9JLOCZkrc9x3sOPjWy4wIUMlFhouy+u1sBAcVSYyVKOx7g8vV4O75PQRmgpWEWbQV9yCOa3jj3Gur3A==}
/@melt-ui/svelte@0.50.0(svelte@4.2.1):
resolution: {integrity: sha512-NcWwxwStXq77/yOuBfnGkuJdUta3M4SwqZECdaRpAQ61BHI3qz7WW2ZM42JmDvGSs9W6ww2kZFNF8XNTO92CdA==}
peerDependencies:
svelte: '>=3 <5'
dependencies:
'@floating-ui/core': 1.4.1
'@floating-ui/dom': 1.5.1
focus-trap: 7.5.2
'@floating-ui/core': 1.5.0
'@floating-ui/dom': 1.5.3
dequal: 2.0.3
focus-trap: 7.5.3
nanoid: 4.0.2
svelte: 4.2.1
@ -1969,6 +1990,17 @@ packages:
- supports-color
dev: false
/boardgamegeekclient@1.9.1:
resolution: {integrity: sha512-sSL27GGYHBp7PEt/j3NyrCpkMWgtu0I0VxYveveU5l5POnBhlSlyESy3rJe/qvHXx55DSE3VuDNeDzHHuIjLHA==}
engines: {node: '>=10'}
dependencies:
fast-xml-parser: 3.21.1
isomorphic-unfetch: 3.1.0
jackson-js: 1.1.0
transitivePeerDependencies:
- encoding
dev: false
/brace-expansion@1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
@ -2558,6 +2590,13 @@ packages:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
dev: true
/fast-xml-parser@3.21.1:
resolution: {integrity: sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg==}
hasBin: true
dependencies:
strnum: 1.0.5
dev: false
/fastq@1.15.0:
resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
dependencies:
@ -2617,6 +2656,12 @@ packages:
resolution: {integrity: sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==}
dependencies:
tabbable: 6.2.0
dev: false
/focus-trap@7.5.3:
resolution: {integrity: sha512-7UsT/eSJcTPF0aZp73u7hBRTABz26knRRTJfoTGFCQD5mUImLIIOwWWCrtoQdmWa7dykBi6H+Cp5i3S/kvsMeA==}
dependencies:
tabbable: 6.2.0
/follow-redirects@1.15.2:
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
@ -2882,6 +2927,24 @@ packages:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true
/isomorphic-unfetch@3.1.0:
resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==}
dependencies:
node-fetch: 2.6.7
unfetch: 4.2.0
transitivePeerDependencies:
- encoding
dev: false
/jackson-js@1.1.0:
resolution: {integrity: sha512-EDKwt9U6dd/zNW/7p3VejSYUYgUkZ5c7v4gGAO7KhA1qLp6DXPpBjIx9ELI9LzQjpFtoL8g6CAQAhBuDmzkYMw==}
dependencies:
lodash.clone: 4.5.0
lodash.clonedeep: 4.5.0
meriyah: 1.9.15
reflect-metadata: 0.1.13
dev: false
/jiti@1.18.2:
resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==}
hasBin: true
@ -2969,6 +3032,14 @@ packages:
p-locate: 5.0.0
dev: true
/lodash.clone@4.5.0:
resolution: {integrity: sha512-GhrVeweiTD6uTmmn5hV/lzgCQhccwReIVRLHp7LT4SopOjqEZ5BbX8b5WWEtAKasjmy8hR7ZPwsYlxRCku5odg==}
dev: false
/lodash.clonedeep@4.5.0:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
dev: false
/lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
@ -3037,6 +3108,11 @@ packages:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
/meriyah@1.9.15:
resolution: {integrity: sha512-D4rT6XIYGqZab0EI/xbihUpwh0WbNRVQ35l2J/5QC2atxaI8h3KvA55DEJLBB/FRdaji7JwkNehfCRjCyjCjqw==}
engines: {node: '>=6.0.0'}
dev: false
/micromatch@4.0.5:
resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
engines: {node: '>=8.6'}
@ -3799,6 +3875,10 @@ packages:
dependencies:
picomatch: 2.3.1
/reflect-metadata@0.1.13:
resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==}
dev: false
/regenerator-runtime@0.13.11:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
dev: false
@ -4051,6 +4131,10 @@ packages:
acorn: 8.10.0
dev: true
/strnum@1.0.5:
resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
dev: false
/sucrase@3.32.0:
resolution: {integrity: sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==}
engines: {node: '>=8'}
@ -4467,6 +4551,10 @@ packages:
dependencies:
busboy: 1.6.0
/unfetch@4.2.0:
resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==}
dev: false
/unicode-trie@2.0.0:
resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==}
dependencies:

View file

@ -0,0 +1,43 @@
import { HttpError_1, error, json } from '@sveltejs/kit';
import { BggClient } from 'boardgamegeekclient';
export async function GET({ url, locals, params }) {
const game_id = Number(params.id).valueOf();
// TODO: Debounce excessive calls and possibly throttle
if (isNaN(game_id) || !isFinite(game_id)) {
throw error(400, { message: 'Invalid game id' });
}
console.log('Searching for', game_id);
const client = BggClient.Create();
const response = await client.thing.query({
id: game_id
});
if (!response || response.length === 0) {
throw error(404, { message: 'No results found in external search' });
}
const result = response[0];
const apiResponse = {
external_id: result.id,
name: result.name,
type: result.type,
description: result.description,
thumbnail: result.thumbnail,
image: result.image,
year_published: result.yearpublished,
min_players: result.minplayers,
max_players: result.maxplayers,
playing_time: result.playingtime,
min_playtime: result.minplaytime,
max_playtime: result.maxplaytime,
min_age: result.minage
};
console.log('Response from BGG', JSON.stringify(result, null, 2));
return json(apiResponse);
}

View file

@ -0,0 +1,57 @@
import { error, json } from '@sveltejs/kit';
import { ZodError } from 'zod';
import { BggClient } from 'boardgamegeekclient';
import type { ISearchRequest } from 'boardgamegeekclient/dist/esm/request/index.js';
import { search_schema } from '$lib/zodValidation.js';
export async function GET({ url, locals, params }) {
const searchParams = Object.fromEntries(url.searchParams);
const q = searchParams?.q || '';
const exact = parseInt(searchParams.exact) || 0;
const limit = parseInt(searchParams?.limit) || 10;
const skip = parseInt(searchParams?.skip) || 0;
console.log('exact', exact);
console.log('limit', limit);
console.log('skip', skip);
// TODO: Debounce and throttle
try {
search_schema.parse({
q,
limit,
skip
});
} catch (e) {
console.error(e);
if (e instanceof ZodError) {
throw error(400, { message: e.flatten().fieldErrors });
}
throw error(500, { message: 'Something went wrong' });
}
const client = BggClient.Create();
const request: ISearchRequest = {
query: q,
exact,
type: ['boardgame', 'boardgameaccessory', 'boardgameexpansion']
};
const response = await client.search.query(request);
if (!response || response.length === 0 || response[0]?.total === 0) {
throw error(404, { message: 'No results found in external search' });
}
const result = response[0];
const start = skip;
let end = start + limit;
if (end > result.total) {
end = result.total;
}
const apiResponse = result.items.slice(start, end);
console.log('Response from BGG', JSON.stringify(result, null, 2));
return json(apiResponse);
}