Fixing all the root imports, installing and adding logging based on auth example.

This commit is contained in:
Bradley Shellnut 2023-05-28 23:34:39 -07:00
parent f35bddc27b
commit 16aad6696d
33 changed files with 707 additions and 353 deletions

View file

@ -17,14 +17,14 @@
"seed": "ts-node --esm prisma/seed.ts"
},
"devDependencies": {
"@playwright/test": "^1.34.1",
"@playwright/test": "^1.34.3",
"@rgossiaux/svelte-headlessui": "1.0.2",
"@rgossiaux/svelte-heroicons": "^0.1.2",
"@sveltejs/adapter-auto": "^1.0.3",
"@sveltejs/adapter-vercel": "^1.0.6",
"@sveltejs/kit": "^1.18.0",
"@sveltejs/kit": "^1.19.0",
"@types/cookie": "^0.5.1",
"@types/node": "^18.16.14",
"@types/node": "^18.16.16",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.7",
"autoprefixer": "^10.4.14",
@ -52,12 +52,13 @@
"ts-node": "^10.9.1",
"tslib": "^2.5.2",
"typescript": "^4.9.5",
"vite": "^4.3.8",
"vite": "^4.3.9",
"vitest": "^0.25.3",
"zod": "^3.21.4"
},
"type": "module",
"dependencies": {
"@axiomhq/axiom-node": "^0.12.0",
"@fontsource/fira-mono": "^4.5.10",
"@iconify-icons/line-md": "^1.2.22",
"@iconify-icons/mdi": "^1.2.46",
@ -76,6 +77,7 @@
"open-props": "^1.5.8",
"svelte-lazy": "^1.2.1",
"svelte-lazy-loader": "^1.0.0",
"sveltekit-flash-message": "^0.11.3",
"zod-to-json-schema": "^3.21.1"
}
}

File diff suppressed because it is too large Load diff

View file

@ -55,4 +55,99 @@ model AuthKey {
enum Role {
USER
ADMIN
}
}
model Game {
id String @id
name String
description String?
yearPublished Int?
minPlayers Int?
maxPlayers Int?
minPlaytime Int?
maxPlaytime Int?
minAge Int?
imageUrl String?
thumbUrl String?
url String?
rulesUrl String?
weightAmount Float?
weightUnits String?
bggId String?
bggUrl String?
primaryPublisher Publisher?
categories Category[]
mechanics Mechanic[]
designers Designer[]
publishers Publisher[]
artists Artist[]
names String[] @db.Array
expansions Expansion[]
@@index([game_id])
@@map("games")
}
model Publisher {
id String @id
name String
games Game[] @relation(references: [id], fields: [game_id])
primaryPublisher Game[] @relation("PrimaryPublisher")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("publishers")
}
model Category {
id String @id
name String
slug String
games Game[] @relation("GameCategories")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("categories")
}
model Mechanic {
id String @id
name String
games Game[] @relation("GameMechanics")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("mechanics")
}
model Designer {
id String @id
name String
games Game[] @relation("GameDesigners")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("designers")
}
model Artist {
id String @id
name String
games Game[] @relation("GameArtists")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("artists")
}
model Expansion {
id String @id
name String
yearPublished Int?
baseGame Game? @relation("Expansions", fields: [baseGameId], references: [id])
baseGameId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("expansions")
}

13
src/app.d.ts vendored
View file

@ -4,9 +4,22 @@
// src/app.d.ts
declare global {
namespace App {
interface PageData {
flash?: { type: 'success' | 'error'; message: string };
}
interface Locals {
auth: import('lucia-auth').AuthRequest;
user: Lucia.UserAttributes;
startTimer: number;
error: string;
errorId: string;
errorStackTrace: string;
message: unknown;
track: unknown;
}
interface Error {
code?: string;
errorId?: string;
}
}
}

View file

@ -1,7 +1,33 @@
import { redirect, type Handle } from '@sveltejs/kit';
import type { HandleServerError } from '@sveltejs/kit';
import { auth } from '$lib/server/lucia';
import log from '$lib/server/log';
import { dev } from '$app/environment';
export const handleError: HandleServerError = async ({ error, event }) => {
const errorId = crypto.randomUUID();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
event.locals.error = error?.toString() || undefined;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
event.locals.errorStackTrace = error?.stack || undefined;
event.locals.errorId = errorId;
if (!dev) {
log(500, event);
}
return {
message: 'An unexpected error occurred.',
errorId
};
};
export const handle: Handle = async ({ event, resolve }) => {
const startTimer = Date.now();
event.locals.startTimer = startTimer;
event.locals.auth = auth.handleRequest(event);
console.log(JSON.stringify(event));
if (event.locals?.auth) {
@ -13,5 +39,9 @@ export const handle: Handle = async ({ event, resolve }) => {
}
}
return await resolve(event);
const response = await resolve(event);
if (!dev) {
log(response.status, event);
}
return response;
};

View file

@ -6,8 +6,8 @@
DialogOverlay,
DialogTitle
} from '@rgossiaux/svelte-headlessui';
import { boredState } from '$root/lib/stores/boredState';
import { collectionStore } from '$root/lib/stores/collectionStore';
import { boredState } from '$lib/stores/boredState';
import { collectionStore } from '$lib/stores/collectionStore';
import { browser } from '$app/environment';
function clearCollection() {

View file

@ -1,7 +1,7 @@
<script lang="ts">
import { browser } from '$app/environment';
import { boredState } from '$root/lib/stores/boredState';
import { wishlistStore } from '$root/lib/stores/wishlistStore';
import { boredState } from '$lib/stores/boredState';
import { wishlistStore } from '$lib/stores/wishlistStore';
import DefaultDialog from './DefaultDialog.svelte';
function clearWishlist() {

View file

@ -7,7 +7,7 @@
DialogOverlay,
DialogTitle
} from '@rgossiaux/svelte-headlessui';
import { boredState } from '$root/lib/stores/boredState';
import { boredState } from '$lib/stores/boredState';
export let title: string;
export let description: string;

View file

@ -6,9 +6,9 @@
DialogOverlay,
DialogTitle
} from '@rgossiaux/svelte-headlessui';
import { boredState } from '$root/lib/stores/boredState';
import { collectionStore } from '$root/lib/stores/collectionStore';
import { removeFromCollection } from '$root/lib/util/manipulateCollection';
import { boredState } from '$lib/stores/boredState';
import { collectionStore } from '$lib/stores/collectionStore';
import { removeFromCollection } from '$lib/util/manipulateCollection';
import { browser } from '$app/environment';
function removeGame() {

View file

@ -6,9 +6,9 @@
DialogOverlay,
DialogTitle
} from '@rgossiaux/svelte-headlessui';
import { boredState } from '$root/lib/stores/boredState';
import { wishlistStore } from '$root/lib/stores/wishlistStore';
import { removeFromWishlist } from '$root/lib/util/manipulateWishlist';
import { boredState } from '$lib/stores/boredState';
import { wishlistStore } from '$lib/stores/wishlistStore';
import { removeFromWishlist } from '$lib/util/manipulateWishlist';
import { browser } from '$app/environment';
function removeGame() {

View file

@ -7,12 +7,12 @@
import Button from '$lib/components/button/index.svelte';
import type { GameType, SavedGameType } from '$lib/types';
import { collectionStore } from '$lib/stores/collectionStore';
import { wishlistStore } from '$root/lib/stores/wishlistStore';
import { wishlistStore } from '$lib/stores/wishlistStore';
import { addToCollection, removeFromCollection } from '$lib/util/manipulateCollection';
import { addToWishlist } from '$lib/util/manipulateWishlist';
import { browser } from '$app/environment';
import { binarySearchOnStore } from '$root/lib/util/binarySearchOnStore';
import { convertToSavedGame } from '$root/lib/util/gameMapper';
import { binarySearchOnStore } from '$lib/util/binarySearchOnStore';
import { convertToSavedGame } from '$lib/util/gameMapper';
export let game: GameType | SavedGameType;
export let detailed: boolean = false;

View file

@ -1,8 +1,8 @@
<script lang="ts">
import { browser } from '$app/environment';
import { boredState } from '$root/lib/stores/boredState';
import { collectionStore } from '$root/lib/stores/collectionStore';
import { ToastType } from '$root/lib/types';
import { boredState } from '$lib/stores/boredState';
import { collectionStore } from '$lib/stores/collectionStore';
import { ToastType } from '$lib/types';
import { SaveIcon, ShareIcon, TrashIcon } from '@rgossiaux/svelte-heroicons/outline';
import ClearCollectionDialog from '../dialog/ClearCollectionDialog.svelte';
import { toast } from '../toast/toast';

View file

@ -1,8 +1,8 @@
<script lang="ts">
import { browser } from '$app/environment';
import { boredState } from '$root/lib/stores/boredState';
import { wishlistStore } from '$root/lib/stores/wishlistStore';
import { ToastType } from '$root/lib/types';
import { boredState } from '$lib/stores/boredState';
import { wishlistStore } from '$lib/stores/wishlistStore';
import { ToastType } from '$lib/types';
import { SaveIcon, ShareIcon, TrashIcon } from '@rgossiaux/svelte-heroicons/outline';
import ClearWishlistDialog from '../dialog/ClearWishlistDialog.svelte';
import { toast } from '../toast/toast';

View file

@ -4,7 +4,7 @@
import { collectionStore } from '$lib/stores/collectionStore';
import { toast } from '$lib/components/toast/toast';
import { ToastType, type SavedGameType } from '$lib/types';
import { mapSavedGameToGame } from '$root/lib/util/gameMapper';
import { mapSavedGameToGame } from '$lib/util/gameMapper';
async function getRandomCollectionGame() {
if ($collectionStore.length > 0) {

View file

@ -21,15 +21,15 @@
cancel();
}
},
onUpdated: ({ form }) => {
if ($gameStore.length <= 0) {
toast.send('No results found 😿', {
duration: 3000,
type: ToastType.ERROR,
dismissible: true
});
}
}
// onUpdated: ({ form }) => {
// if ($gameStore.length <= 0) {
// toast.send('No results found 😿', {
// duration: 3000,
// type: ToastType.ERROR,
// dismissible: true
// });
// }
// }
});
let submitting = $boredState?.loading;

View file

@ -10,11 +10,11 @@
import { boredState } from '$lib/stores/boredState';
import AdvancedSearch from '$lib/components/search/advancedSearch/index.svelte';
import { xl, md, sm } from '$lib/stores/mediaQueryStore';
import { gameStore } from '$root/lib/stores/gameSearchStore';
import { gameStore } from '$lib/stores/gameSearchStore';
import { toast } from '../../toast/toast';
import Pagination from '$lib/components/pagination/index.svelte';
import Game from '$lib/components/game/index.svelte';
import { ToastType, type GameType, type SavedGameType } from '$root/lib/types';
import { ToastType, type GameType, type SavedGameType } from '$lib/types';
import SkeletonPlaceholder from '../../SkeletonPlaceholder.svelte';
import RemoveCollectionDialog from '../../dialog/RemoveCollectionDialog.svelte';
import RemoveWishlistDialog from '../../dialog/RemoveWishlistDialog.svelte';

View file

@ -1,3 +1,4 @@
import { dev } from '$app/environment';
export const BASE_URL = dev ? 'http://localhost:5173' : 'https://boredgame.vercel.app';
export const APP_NAME = 'Bored Game';
export const DOMAIN = 'boredgame.vercel.app';

70
src/lib/server/log.ts Normal file
View file

@ -0,0 +1,70 @@
import { Client } from '@axiomhq/axiom-node';
import { AXIOM_TOKEN, AXIOM_ORG_ID, AXIOM_DATASET } from '$env/static/private';
import getAllUrlParams from '$lib/util/getAllUrlParams';
import parseTrack from '$lib/util/parseTrack';
import parseMessage from '$lib/util/parseMessage';
import { DOMAIN } from '$lib/config/constants';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
export default async function log(statusCode: number, event) {
try {
let level = 'info';
if (statusCode >= 400) {
level = 'error';
}
const error = event?.locals?.error || undefined;
const errorId = event?.locals?.errorId || undefined;
const errorStackTrace = event?.locals?.errorStackTrace || undefined;
let urlParams = {};
if (event?.url?.search) {
urlParams = await getAllUrlParams(event?.url?.search);
}
let messageEvents = {};
if (event?.locals?.message) {
messageEvents = await parseMessage(event?.locals?.message);
}
let trackEvents = {};
if (event?.locals?.track) {
trackEvents = await parseTrack(event?.locals?.track);
}
let referer = event.request.headers.get('referer');
if (referer) {
const refererUrl = await new URL(referer);
const refererHostname = refererUrl.hostname;
if (refererHostname === 'localhost' || refererHostname === DOMAIN) {
referer = refererUrl.pathname;
}
} else {
referer = undefined;
}
const logData: object = {
level: level,
method: event.request.method,
path: event.url.pathname,
status: statusCode,
timeInMs: Date.now() - event?.locals?.startTimer,
user: event?.locals?.user?.email,
userId: event?.locals?.user?.userId,
referer: referer,
error: error,
errorId: errorId,
errorStackTrace: errorStackTrace,
...urlParams,
...messageEvents,
...trackEvents
};
console.log('log: ', JSON.stringify(logData));
if (!AXIOM_TOKEN || !AXIOM_ORG_ID || !AXIOM_DATASET) {
return;
}
const client = new Client({
token: AXIOM_TOKEN,
orgId: AXIOM_ORG_ID
});
await client.ingestEvents(AXIOM_DATASET, [logData]);
} catch (err) {
throw new Error(`Error Logger: ${JSON.stringify(err)}`);
}
}

View file

@ -0,0 +1,11 @@
export default async function getAllUrlParams(url: string): Promise<object> {
let paramsObj = {};
try {
url = url?.slice(1); // remove leading ?
if (!url) return {}; // if no params return
paramsObj = await Object.fromEntries(await new URLSearchParams(url));
} catch (error) {
console.log('error: ', error);
}
return paramsObj;
}

View file

@ -0,0 +1,15 @@
export default async function parseMessage(message: unknown): Promise<object> {
let messageObj = {};
try {
if (message) {
if (typeof message === 'string') {
messageObj = { message: message };
} else {
messageObj = message;
}
}
} catch (error) {
console.log('error: ', error);
}
return messageObj;
}

View file

@ -0,0 +1,15 @@
export default async function parseTrack(track: unknown): Promise<object> {
let trackObj = {};
try {
if (track) {
if (typeof track === 'string') {
trackObj = { track: track };
} else {
trackObj = track;
}
}
} catch (error) {
console.log('error: ', error);
}
return trackObj;
}

View file

@ -1,4 +1,20 @@
<h1>The page you requested doesn't exist! 🤷‍♂️</h1>
<script lang="ts">
import { page } from '$app/stores';
</script>
<div>
{#if $page.status === 404}
<h1>The page you requested doesn't exist! 🤷‍♂️</h1>
<h3 class="mt-6"><a href="/">Go Home</a></h3>
{:else}
<h1 class="h1">Unexpected Error</h1>
<h3 class="mt-6">We're investigating the issue.</h3>
{/if}
{#if $page.error?.errorId}
<p class="mt-6">Error ID: {$page.error.errorId}</p>
{/if}
</div>
<style>
h1 {

View file

@ -12,7 +12,7 @@
import Portal from '$lib/Portal.svelte';
import { boredState } from '$lib/stores/boredState';
import { collectionStore } from '$lib/stores/collectionStore';
import { wishlistStore } from '$root/lib/stores/wishlistStore';
import { wishlistStore } from '$lib/stores/wishlistStore';
import { gameStore } from '$lib/stores/gameSearchStore';
import { toast } from '$lib/components/toast/toast';
import Toast from '$lib/components/toast/Toast.svelte';

View file

@ -3,8 +3,10 @@ import { search_schema } from '$lib/zodValidation';
export const load = async ({ fetch, url }) => {
const formData = Object.fromEntries(url?.searchParams);
console.log('formData', formData);
formData.name = formData?.q;
const form = await superValidate(formData, search_schema);
console.log('form', form);
return { form };
};

View file

@ -13,10 +13,10 @@ export const load = async (event) => {
if (session) {
throw redirect(302, '/');
}
const form = await superValidate(event, signInSchema);
return {
form
};
// const form = await superValidate(event, signInSchema);
// return {
// form
// };
};
export const actions = {
@ -24,6 +24,7 @@ export const actions = {
const form = await superValidate(event, signInSchema);
if (!form.valid) {
form.data.password = '';
return fail(400, {
form
});
@ -31,16 +32,17 @@ export const actions = {
// Adding user to the db
try {
console.log('sign in user');
const key = await auth.useKey('username', form.data.username, form.data.password);
const session = await auth.createSession(key.userId);
event.locals.auth.setSession(session);
} catch (e) {
// TODO: need to return error message to the client
console.error(e);
form.data.password = '';
return setError(form, null, 'The username or password is incorrect.');
}
form.data.username = '';
form.data.password = '';
return { form };
}
};

View file

@ -7,6 +7,7 @@
const { form, errors, enhance, delayed } = superForm(data.form, {
taintedMessage: null,
validators: signInSchema,
validationMethod: 'oninput',
delayMs: 0,
});
</script>

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { userSchema } from '$root/lib/config/zod-schemas.js';
import { userSchema } from '$lib/config/zod-schemas.js';
import { superForm } from 'sveltekit-superforms/client';
export let data;

View file

@ -2,12 +2,12 @@
import { tick, onDestroy } from 'svelte';
import Game from '$lib/components/game/index.svelte';
import { collectionStore } from '$lib/stores/collectionStore';
import type { GameType, SavedGameType } from '$root/lib/types';
import { boredState } from '$root/lib/stores/boredState';
import Pagination from '$root/lib/components/pagination/index.svelte';
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
import { createSearchStore, searchHandler } from '$root/lib/stores/search';
import type { GameType, SavedGameType } from '$lib/types';
import { boredState } from '$lib/stores/boredState';
import Pagination from '$lib/components/pagination/index.svelte';
import RemoveCollectionDialog from '$lib/components/dialog/RemoveCollectionDialog.svelte';
import RemoveWishlistDialog from '$lib/components/dialog/RemoveWishlistDialog.svelte';
import { createSearchStore, searchHandler } from '$lib/stores/search';
import type { PageData } from './$types';
export let data: PageData;

View file

@ -15,16 +15,16 @@
import { collectionStore } from '$lib/stores/collectionStore';
import { wishlistStore } from '$lib/stores/wishlistStore';
import Button from '$lib/components/button/index.svelte';
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
import RemoveCollectionDialog from '$lib/components/dialog/RemoveCollectionDialog.svelte';
import { addToCollection } from '$lib/util/manipulateCollection';
import type { PageData } from './$types';
import { boredState } from '$root/lib/stores/boredState';
import { boredState } from '$lib/stores/boredState';
import { browser } from '$app/environment';
import LinkWithIcon from '$root/lib/components/LinkWithIcon.svelte';
import { addToWishlist } from '$root/lib/util/manipulateWishlist';
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
import { binarySearchOnStore } from '$root/lib/util/binarySearchOnStore';
import { convertToSavedGame } from '$root/lib/util/gameMapper';
import LinkWithIcon from '$lib/components/LinkWithIcon.svelte';
import { addToWishlist } from '$lib/util/manipulateWishlist';
import RemoveWishlistDialog from '$lib/components/dialog/RemoveWishlistDialog.svelte';
import { binarySearchOnStore } from '$lib/util/binarySearchOnStore';
import { convertToSavedGame } from '$lib/util/gameMapper';
$: existsInCollection = $collectionStore.find((item: SavedGameType) => item.id === game.id);
$: existsInWishlist = $wishlistStore.find((item: SavedGameType) => item.id === game.id);

View file

@ -2,12 +2,12 @@
import { tick, onDestroy } from 'svelte';
import Game from '$lib/components/game/index.svelte';
import { wishlistStore } from '$lib/stores/wishlistStore';
import type { GameType, SavedGameType } from '$root/lib/types';
import { boredState } from '$root/lib/stores/boredState';
import Pagination from '$root/lib/components/pagination/index.svelte';
import RemoveWishlistDialog from '$root/lib/components/dialog/RemoveWishlistDialog.svelte';
import RemoveCollectionDialog from '$root/lib/components/dialog/RemoveCollectionDialog.svelte';
import { createSearchStore, searchHandler } from '$root/lib/stores/search';
import type { GameType, SavedGameType } from '$lib/types';
import { boredState } from '$lib/stores/boredState';
import Pagination from '$lib/components/pagination/index.svelte';
import RemoveWishlistDialog from '$lib/components/dialog/RemoveWishlistDialog.svelte';
import RemoveCollectionDialog from '$lib/components/dialog/RemoveCollectionDialog.svelte';
import { createSearchStore, searchHandler } from '$lib/stores/search';
let gameToRemove: GameType | SavedGameType;
let pageSize = 10;

View file

@ -1,181 +1,181 @@
import { invalid, type RequestEvent } from '@sveltejs/kit';
import { BOARD_GAME_ATLAS_CLIENT_ID } from '$env/static/private';
import type { GameType, SearchQuery } from "$root/lib/types";
import { mapAPIGameToBoredGame } from "$root/lib/util/gameMapper";
import type { GameType, SearchQuery } from '$lib/types';
import { mapAPIGameToBoredGame } from '$lib/util/gameMapper';
interface Actions {
[key: string]: any // Action
[key: string]: any; // Action
}
export const Games: Actions = {
search: async ({ request, locals }: RequestEvent): Promise<any> => {
console.log("In search action specific")
// Do things in here
const form = await request.formData();
console.log('action form', form);
const queryParams: SearchQuery = {
order_by: 'rank',
ascending: false,
limit: 10,
skip: 0,
client_id: BOARD_GAME_ATLAS_CLIENT_ID,
fuzzy_match: true,
name: ''
};
search: async ({ request, locals }: RequestEvent): Promise<any> => {
console.log('In search action specific');
// Do things in here
const form = await request.formData();
console.log('action form', form);
const queryParams: SearchQuery = {
order_by: 'rank',
ascending: false,
limit: 10,
skip: 0,
client_id: BOARD_GAME_ATLAS_CLIENT_ID,
fuzzy_match: true,
name: ''
};
const name = form.has('name') ? form.get('name') : await request?.text();
console.log('name', name);
if (name) {
queryParams.name = `${name}`;
}
const name = form.has('name') ? form.get('name') : await request?.text();
console.log('name', name);
if (name) {
queryParams.name = `${name}`;
}
const newQueryParams: Record<string, string> = {};
for (const key in queryParams) {
console.log('key', key);
console.log('queryParams[key]', queryParams[key]);
newQueryParams[key] = `${queryParams[key]}`;
}
const newQueryParams: Record<string, string> = {};
for (const key in queryParams) {
console.log('key', key);
console.log('queryParams[key]', queryParams[key]);
newQueryParams[key] = `${queryParams[key]}`;
}
const urlQueryParams = new URLSearchParams(newQueryParams);
console.log('urlQueryParams', urlQueryParams);
const urlQueryParams = new URLSearchParams(newQueryParams);
console.log('urlQueryParams', urlQueryParams);
try {
throw new Error("test error");
// const url = `https://api.boardgameatlas.com/api/search${urlQueryParams ? `?${urlQueryParams}` : ''
// }`;
// const response = await fetch(url, {
// method: 'get',
// headers: {
// 'content-type': 'application/json'
// }
// });
// console.log('board game response', response);
// if (response.status !== 200) {
// console.log('Status not 200', response.status)
// invalid(response.status, {});
// }
try {
throw new Error('test error');
// const url = `https://api.boardgameatlas.com/api/search${urlQueryParams ? `?${urlQueryParams}` : ''
// }`;
// const response = await fetch(url, {
// method: 'get',
// headers: {
// 'content-type': 'application/json'
// }
// });
// console.log('board game response', response);
// if (response.status !== 200) {
// console.log('Status not 200', response.status)
// invalid(response.status, {});
// }
// if (response.status === 200) {
// const gameResponse = await response.json();
// console.log('gameResponse', gameResponse);
// const gameList = gameResponse?.games;
// const totalCount = gameResponse?.count;
// console.log('totalCount', totalCount);
// const games: GameType[] = [];
// gameList.forEach((game) => {
// games.push(mapAPIGameToBoredGame(game));
// });
// if (response.status === 200) {
// const gameResponse = await response.json();
// console.log('gameResponse', gameResponse);
// const gameList = gameResponse?.games;
// const totalCount = gameResponse?.count;
// console.log('totalCount', totalCount);
// const games: GameType[] = [];
// gameList.forEach((game) => {
// games.push(mapAPIGameToBoredGame(game));
// });
// console.log('returning from search')
// console.log('returning from search')
// return {
// games,
// totalCount: games.length
// };
// }
// return {
// games,
// totalCount: games.length
// };
// }
// return {
// games: [],
// totalCount: 0
// };
} catch (e) {
console.log(`Error searching board games ${e}`);
return invalid(400, { reason: 'Exception' })
}
}
// return {
// games: [],
// totalCount: 0
// };
} catch (e) {
console.log(`Error searching board games ${e}`);
return invalid(400, { reason: 'Exception' });
}
}
// const id = form.get('id');
// const ids = form.get('ids');
// const minAge = form.get('minAge');
// const minPlayers = form.get('minPlayers');
// const maxPlayers = form.get('maxPlayers');
// const exactMinAge = form.get('exactMinAge') || false;
// const exactMinPlayers = form.get('exactMinPlayers') || false;
// const exactMaxPlayers = form.get('exactMaxPlayers') || false;
// const random = form.get('random') === 'on' || false;
// const id = form.get('id');
// const ids = form.get('ids');
// const minAge = form.get('minAge');
// const minPlayers = form.get('minPlayers');
// const maxPlayers = form.get('maxPlayers');
// const exactMinAge = form.get('exactMinAge') || false;
// const exactMinPlayers = form.get('exactMinPlayers') || false;
// const exactMaxPlayers = form.get('exactMaxPlayers') || false;
// const random = form.get('random') === 'on' || false;
// if (minAge) {
// if (exactMinAge) {
// queryParams.min_age = +minAge;
// } else {
// queryParams.gt_min_age = +minAge === 1 ? 0 : +minAge - 1;
// }
// }
// if (minAge) {
// if (exactMinAge) {
// queryParams.min_age = +minAge;
// } else {
// queryParams.gt_min_age = +minAge === 1 ? 0 : +minAge - 1;
// }
// }
// if (minPlayers) {
// if (exactMinPlayers) {
// queryParams.min_players = +minPlayers;
// } else {
// queryParams.gt_min_players = +minPlayers === 1 ? 0 : +minPlayers - 1;
// }
// }
// if (minPlayers) {
// if (exactMinPlayers) {
// queryParams.min_players = +minPlayers;
// } else {
// queryParams.gt_min_players = +minPlayers === 1 ? 0 : +minPlayers - 1;
// }
// }
// if (maxPlayers) {
// if (exactMaxPlayers) {
// queryParams.max_players = +maxPlayers;
// } else {
// queryParams.lt_max_players = +maxPlayers + 1;
// }
// }
// if (maxPlayers) {
// if (exactMaxPlayers) {
// queryParams.max_players = +maxPlayers;
// } else {
// queryParams.lt_max_players = +maxPlayers + 1;
// }
// }
// if (id) {
// queryParams.ids = new Array(`${id}`);
// }
// if (id) {
// queryParams.ids = new Array(`${id}`);
// }
// if (ids) {
// // TODO: Pass in ids array from localstorage / game store
// queryParams.ids = new Array(ids);
// }
// if (ids) {
// // TODO: Pass in ids array from localstorage / game store
// queryParams.ids = new Array(ids);
// }
// queryParams.random = random;
// console.log('queryParams', queryParams);
// queryParams.random = random;
// console.log('queryParams', queryParams);
// const newQueryParams: Record<string, string> = {};
// for (const key in queryParams) {
// newQueryParams[key] = `${queryParams[key as keyof typeof queryParams]}`;
// }
// const newQueryParams: Record<string, string> = {};
// for (const key in queryParams) {
// newQueryParams[key] = `${queryParams[key as keyof typeof queryParams]}`;
// }
// const urlQueryParams = new URLSearchParams(newQueryParams);
// const urlQueryParams = new URLSearchParams(newQueryParams);
// const url = `https://api.boardgameatlas.com/api/search${urlQueryParams ? `?${urlQueryParams}` : ''
// }`;
// const response = await fetch(url, {
// method: 'get',
// headers: {
// 'content-type': 'application/json'
// }
// });
// console.log('response status', response.status);
// console.log('board game response action', response);
// if (response.status === 404) {
// // user hasn't created a todo list.
// // start with an empty array
// return {
// success: true,
// games: [],
// totalCount: 0
// };
// }
// const url = `https://api.boardgameatlas.com/api/search${urlQueryParams ? `?${urlQueryParams}` : ''
// }`;
// const response = await fetch(url, {
// method: 'get',
// headers: {
// 'content-type': 'application/json'
// }
// });
// console.log('response status', response.status);
// console.log('board game response action', response);
// if (response.status === 404) {
// // user hasn't created a todo list.
// // start with an empty array
// return {
// success: true,
// games: [],
// totalCount: 0
// };
// }
// if (response.status === 200) {
// const gameResponse = await response.json();
// console.log('gameResponse', gameResponse);
// const gameList = gameResponse?.games;
// const games: GameType[] = [];
// gameList.forEach((game: GameType) => {
// games.push(mapAPIGameToBoredGame(game));
// });
// console.log('action games', games);
// return {
// games,
// totalCount: games.length
// };
// }
// if (response.status === 200) {
// const gameResponse = await response.json();
// console.log('gameResponse', gameResponse);
// const gameList = gameResponse?.games;
// const games: GameType[] = [];
// gameList.forEach((game: GameType) => {
// games.push(mapAPIGameToBoredGame(game));
// });
// console.log('action games', games);
// return {
// games,
// totalCount: games.length
// };
// }
// return { success: false };
// }
// create: async function create({ request, locals }): Promise<any> {
// const data = await getFormDataObject<any>(request);
// return data;
// }
}
// return { success: false };
// }
// create: async function create({ request, locals }): Promise<any> {
// const data = await getFormDataObject<any>(request);
// return data;
// }
};

View file

@ -1,3 +1,3 @@
@import 'reset.pcss';
@import 'global.pcss';
@import '$root/styles/theme.pcss';
@import 'theme.pcss';

View file

@ -14,20 +14,16 @@ const config = {
postcss: true
})
],
vitePlugin: {
inspector: true,
},
kit: {
adapter: adapter(),
alias: {
$root: './src',
$lib: './src/lib',
$styles: './src/styles',
}
},
vitePlugin: {
experimental: {
inspector: {
toggleKeyCombo: 'control-alt-shift'
}
}
}
};
export default config;