mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:41:09 +02:00
fix(mana/web): coerce $page.params.* away from string|undefined
SvelteKit types `$page.params.X` as `string | undefined` because the
runtime cannot prove a route param exists at the type level — even
if the route file lives at e.g. `[id]/+page.svelte` and TS knows the
folder name. Thirteen route files were passing the raw param into
functions that take `string`, producing 25 type errors of the shape:
Argument of type 'string | undefined' is not assignable to
parameter of type 'string'.
Fix: hoist the param into a local with `?? ''` at the top of the
script, then use the local everywhere downstream. Empty string is
a safe fallback because the consuming code (`useDeck('')`,
`getCollectionById([], '')`, etc.) all return null/undefined for
unknown ids — exactly what they'd do if the param were truly
missing at runtime, which can't happen given the matching route
folder.
Files touched (one param hoist each):
calendar/event/[id] eventId
cards/decks/[id] deckId
citycorners/.../locations/[id] citySlug + locId
citycorners/.../locations/[id]/edit citySlug + locId
gifts/redeem/[code] code
inventory/collections/[id] collectionId
inventory/collections/[id]/edit collectionId
inventory/items/[id] itemId
photos/albums/[id] albumId
picture/board/[id] boardId
storage/files/[folderId] folderId
zitare/lists/[id] listId (new local, replaces inline use)
g/[code] code
Net: -24 type errors. The lone remaining "string | undefined" error
is a different bug in inventory FieldDefinition typing — unrelated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ff6118fc3b
commit
b32de06f2a
13 changed files with 22 additions and 20 deletions
|
|
@ -13,7 +13,7 @@
|
|||
const calendarsCtx: { readonly value: Calendar[] } = getContext('calendars');
|
||||
const eventsCtx: { readonly value: CalendarEvent[] } = getContext('calendarEvents');
|
||||
|
||||
let eventId = $derived($page.params.id);
|
||||
let eventId = $derived($page.params.id ?? '');
|
||||
let event = $derived(getEventById(eventsCtx.value, eventId));
|
||||
let calendar = $derived(
|
||||
event ? getCalendarById(calendarsCtx.value, event.calendarId) : undefined
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
import { ArrowLeft, Trash, Plus, ShareNetwork } from '@mana/shared-icons';
|
||||
import { ShareModal } from '@mana/shared-uload';
|
||||
|
||||
let deckId = $derived($page.params.id);
|
||||
let deckId = $derived($page.params.id ?? '');
|
||||
let showDeleteConfirm = $state(false);
|
||||
let deleting = $state(false);
|
||||
let showShare = $state(false);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
const cityCtx = getContext<{ value: LocalCity | undefined }>('currentCity');
|
||||
let city = $derived(cityCtx.value);
|
||||
let citySlug = $derived($page.params.slug);
|
||||
let citySlug = $derived($page.params.slug ?? '');
|
||||
|
||||
const allFavorites = useAllFavorites();
|
||||
let favoriteIds = $derived(getFavoriteIds(allFavorites.value));
|
||||
|
|
@ -96,7 +96,7 @@
|
|||
|
||||
onMount(async () => {
|
||||
try {
|
||||
const locId = $page.params.id;
|
||||
const locId = $page.params.id ?? '';
|
||||
const loc = await ccLocationTable.get(locId);
|
||||
if (loc) {
|
||||
location = {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@
|
|||
|
||||
const cityCtx = getContext<{ value: LocalCity | undefined }>('currentCity');
|
||||
let city = $derived(cityCtx.value);
|
||||
let citySlug = $derived($page.params.slug);
|
||||
let citySlug = $derived($page.params.slug ?? '');
|
||||
let locId = $derived(locId ?? '');
|
||||
|
||||
let loading = $state(true);
|
||||
let name = $state('');
|
||||
|
|
@ -43,7 +44,7 @@
|
|||
|
||||
onMount(async () => {
|
||||
try {
|
||||
const loc = await ccLocationTable.get($page.params.id);
|
||||
const loc = await ccLocationTable.get(locId);
|
||||
if (!loc) {
|
||||
error = $_('edit.loadError');
|
||||
return;
|
||||
|
|
@ -68,14 +69,14 @@
|
|||
error = '';
|
||||
|
||||
try {
|
||||
await ccLocationTable.update($page.params.id, {
|
||||
await ccLocationTable.update(locId, {
|
||||
name: name.trim(),
|
||||
category: category as any,
|
||||
description: description.trim(),
|
||||
address: address.trim() || null,
|
||||
imageUrl: imageUrl.trim() || null,
|
||||
});
|
||||
goto(`/citycorners/cities/${citySlug}/locations/${$page.params.id}`);
|
||||
goto(`/citycorners/cities/${citySlug}/locations/${locId}`);
|
||||
} catch {
|
||||
error = $_('edit.error');
|
||||
} finally {
|
||||
|
|
@ -91,7 +92,7 @@
|
|||
<header class="mb-6">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<a
|
||||
href="/citycorners/cities/{citySlug}/locations/{$page.params.id}"
|
||||
href="/citycorners/cities/{citySlug}/locations/{locId}"
|
||||
class="text-foreground-secondary hover:text-primary transition-colors"
|
||||
>
|
||||
<CaretLeft size={16} />
|
||||
|
|
@ -112,7 +113,7 @@
|
|||
<span class="mb-2 block text-4xl">🔒</span>
|
||||
<p class="text-foreground-secondary">{$_('edit.forbidden')}</p>
|
||||
<a
|
||||
href="/citycorners/cities/{citySlug}/locations/{$page.params.id}"
|
||||
href="/citycorners/cities/{citySlug}/locations/{locId}"
|
||||
class="mt-4 inline-block text-sm text-primary hover:underline"
|
||||
>
|
||||
{$_('detail.back')}
|
||||
|
|
@ -252,7 +253,7 @@
|
|||
|
||||
<div class="flex gap-3">
|
||||
<a
|
||||
href="/citycorners/cities/{citySlug}/locations/{$page.params.id}"
|
||||
href="/citycorners/cities/{citySlug}/locations/{locId}"
|
||||
class="rounded-lg border border-border bg-background px-4 py-3 text-sm font-medium text-foreground-secondary transition-colors hover:bg-background-card-hover"
|
||||
>
|
||||
{$_('edit.cancel')}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
import { Card, PageHeader } from '@mana/shared-ui';
|
||||
import { giftsService, type GiftCodeInfo } from '$lib/api/gifts';
|
||||
|
||||
let code = $derived($page.params.code);
|
||||
let code = $derived($page.params.code ?? '');
|
||||
let giftInfo = $state<GiftCodeInfo | null>(null);
|
||||
let loading = $state(true);
|
||||
let redeeming = $state(false);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
const collectionsCtx: { readonly value: Collection[] } = getContext('collections');
|
||||
const itemsCtx: { readonly value: Item[] } = getContext('items');
|
||||
|
||||
let collectionId = $derived($page.params.id);
|
||||
let collectionId = $derived($page.params.id ?? '');
|
||||
let collection = $derived(getCollectionById(collectionsCtx.value, collectionId));
|
||||
let items = $derived(getItemsByCollection(itemsCtx.value, collectionId));
|
||||
let sortedItems = $derived(getSortedItems(items, viewStore.sort));
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
const collectionsCtx: { readonly value: Collection[] } = getContext('collections');
|
||||
|
||||
let collectionId = $derived($page.params.id);
|
||||
let collectionId = $derived($page.params.id ?? '');
|
||||
let collection = $derived(getCollectionById(collectionsCtx.value, collectionId));
|
||||
|
||||
let name = $state('');
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
const locationsCtx: { readonly value: Location[] } = getContext('locations');
|
||||
const categoriesCtx: { readonly value: Category[] } = getContext('categories');
|
||||
|
||||
let itemId = $derived($page.params.id);
|
||||
let itemId = $derived($page.params.id ?? '');
|
||||
let item = $derived(getItemById(itemsCtx.value, itemId));
|
||||
let collection = $derived(
|
||||
item ? getCollectionById(collectionsCtx.value, item.collectionId) : undefined
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
const allAlbums: { readonly value: Album[] } = getContext('albums');
|
||||
const allAlbumItems: { readonly value: AlbumItem[] } = getContext('albumItems');
|
||||
|
||||
const albumId = $derived($page.params.id);
|
||||
const albumId = $derived($page.params.id ?? '');
|
||||
let currentAlbum = $derived(getAlbumById(allAlbums.value, albumId));
|
||||
let albumItems = $derived(getAlbumItemsForAlbum(allAlbumItems.value, albumId));
|
||||
let albumPhotos = $derived(albumItems.map((item) => ({ id: item.mediaId }) as Photo));
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
const allBoards: { value: BoardWithCount[] } = getContext('allBoards');
|
||||
|
||||
let boardId = $derived($page.params.id);
|
||||
let boardId = $derived($page.params.id ?? '');
|
||||
let board = $derived(findBoardById(allBoards.value, boardId));
|
||||
|
||||
// Edit state
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
const allFiles: { readonly value: StorageFile[] } = getContext('storageFiles');
|
||||
const allFolders: { readonly value: StorageFolder[] } = getContext('storageFolders');
|
||||
|
||||
let folderId = $derived($page.params.folderId);
|
||||
let folderId = $derived($page.params.folderId ?? '');
|
||||
|
||||
// Current folder and its contents
|
||||
let currentFolder = $derived(findFolderById(allFolders?.value ?? [], folderId));
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@
|
|||
let selectedQuoteIds = $state<Set<string>>(new Set());
|
||||
|
||||
// Reactive list from liveQuery context
|
||||
let list = $derived<QuoteList | undefined>(findListById(allLists.value, $page.params.id));
|
||||
let listId = $derived($page.params.id ?? '');
|
||||
let list = $derived<QuoteList | undefined>(findListById(allLists.value, listId));
|
||||
|
||||
// Get quotes in this list
|
||||
let listQuotes = $derived<Quote[]>(
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import { page } from '$app/stores';
|
||||
import { giftsService, type GiftCodeInfo } from '$lib/api/gifts';
|
||||
|
||||
let code = $derived($page.params.code);
|
||||
let code = $derived($page.params.code ?? '');
|
||||
let giftInfo = $state<GiftCodeInfo | null>(null);
|
||||
let loading = $state(true);
|
||||
let error = $state<string | null>(null);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue